@flamingo-stack/openframe-frontend-core 0.0.439 → 0.0.440

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 (467) hide show
  1. package/dist/{chunk-RVWC4P3H.js → chunk-2BTDPDME.js} +9 -9
  2. package/dist/chunk-2BTDPDME.js.map +1 -0
  3. package/dist/{chunk-G5FALXNO.js → chunk-63TSTDME.js} +21 -21
  4. package/dist/chunk-63TSTDME.js.map +1 -0
  5. package/dist/{chunk-4ACSUJ7Q.js → chunk-6CITW5BD.js} +10 -10
  6. package/dist/chunk-6CITW5BD.js.map +1 -0
  7. package/dist/{chunk-QXYOGJQJ.js → chunk-7KDR5P23.js} +2 -2
  8. package/dist/{chunk-PEIR7D25.js → chunk-7KNOHGMI.js} +2 -2
  9. package/dist/{chunk-ZMUFTGL7.cjs → chunk-7QP65IE4.cjs} +5 -5
  10. package/dist/{chunk-ZMUFTGL7.cjs.map → chunk-7QP65IE4.cjs.map} +1 -1
  11. package/dist/{chunk-WPVBTVI3.js → chunk-AGV26PUR.js} +6 -6
  12. package/dist/{chunk-WPVBTVI3.js.map → chunk-AGV26PUR.js.map} +1 -1
  13. package/dist/{chunk-HTVVXVJL.cjs → chunk-DUQQEQ7G.cjs} +1431 -1594
  14. package/dist/chunk-DUQQEQ7G.cjs.map +1 -0
  15. package/dist/{chunk-COMBYYQY.js → chunk-FPE3SQ5D.js} +13 -13
  16. package/dist/chunk-FPE3SQ5D.js.map +1 -0
  17. package/dist/{chunk-WAGTZVQN.js → chunk-IAZ5AN2E.js} +30 -30
  18. package/dist/chunk-IAZ5AN2E.js.map +1 -0
  19. package/dist/{chunk-RQQZF6G6.cjs → chunk-IPEIOR77.cjs} +130 -130
  20. package/dist/chunk-IPEIOR77.cjs.map +1 -0
  21. package/dist/{chunk-3WJQL4DN.cjs → chunk-IZ6A6K6N.cjs} +25 -25
  22. package/dist/chunk-IZ6A6K6N.cjs.map +1 -0
  23. package/dist/{chunk-EE5NH5SH.cjs → chunk-J5NO7PAG.cjs} +3 -3
  24. package/dist/{chunk-EE5NH5SH.cjs.map → chunk-J5NO7PAG.cjs.map} +1 -1
  25. package/dist/{chunk-IAN7GUIV.cjs → chunk-JNC4LVD6.cjs} +42 -42
  26. package/dist/chunk-JNC4LVD6.cjs.map +1 -0
  27. package/dist/{chunk-VWGF6IFR.cjs → chunk-JOH5D76X.cjs} +108 -108
  28. package/dist/chunk-JOH5D76X.cjs.map +1 -0
  29. package/dist/{chunk-7WM77CSW.js → chunk-JYI4R25Q.js} +5 -5
  30. package/dist/chunk-JYI4R25Q.js.map +1 -0
  31. package/dist/{chunk-M6QGB6DC.cjs → chunk-KUXGQ2FQ.cjs} +36 -36
  32. package/dist/chunk-KUXGQ2FQ.cjs.map +1 -0
  33. package/dist/{chunk-M3LD6DNE.cjs → chunk-LFWPWIAC.cjs} +16 -16
  34. package/dist/{chunk-M3LD6DNE.cjs.map → chunk-LFWPWIAC.cjs.map} +1 -1
  35. package/dist/{chunk-R46QEE3R.cjs → chunk-LUKRPHEW.cjs} +96 -96
  36. package/dist/chunk-LUKRPHEW.cjs.map +1 -0
  37. package/dist/{chunk-IMK6RUEC.cjs → chunk-PYR4LVAF.cjs} +10 -10
  38. package/dist/chunk-PYR4LVAF.cjs.map +1 -0
  39. package/dist/{chunk-2ELBNZJ3.js → chunk-QAG357PE.js} +7 -7
  40. package/dist/chunk-QAG357PE.js.map +1 -0
  41. package/dist/{chunk-N2TJ3HAM.cjs → chunk-QO6MCQYE.cjs} +9 -9
  42. package/dist/chunk-QO6MCQYE.cjs.map +1 -0
  43. package/dist/{chunk-EGRZHR7J.js → chunk-SM26C2L7.js} +9 -9
  44. package/dist/chunk-SM26C2L7.js.map +1 -0
  45. package/dist/{chunk-AUJXLVXA.cjs → chunk-TAQMYVO6.cjs} +42 -42
  46. package/dist/{chunk-AUJXLVXA.cjs.map → chunk-TAQMYVO6.cjs.map} +1 -1
  47. package/dist/{chunk-C3FH53AP.cjs → chunk-UFBUQO7Z.cjs} +19 -19
  48. package/dist/{chunk-C3FH53AP.cjs.map → chunk-UFBUQO7Z.cjs.map} +1 -1
  49. package/dist/{chunk-F7YVI54P.js → chunk-W3JZXLJ2.js} +10 -10
  50. package/dist/chunk-W3JZXLJ2.js.map +1 -0
  51. package/dist/{chunk-WZ6TCAYQ.cjs → chunk-XMCVUYKC.cjs} +14 -14
  52. package/dist/chunk-XMCVUYKC.cjs.map +1 -0
  53. package/dist/{chunk-P7PISHM5.js → chunk-Y3NFB6HR.js} +5 -5
  54. package/dist/chunk-Y3NFB6HR.js.map +1 -0
  55. package/dist/{chunk-PBTY7AH5.js → chunk-YZJUHEPZ.js} +95 -95
  56. package/dist/chunk-YZJUHEPZ.js.map +1 -0
  57. package/dist/{chunk-NQQ4NLUT.js → chunk-ZQYFDYWV.js} +4298 -4461
  58. package/dist/chunk-ZQYFDYWV.js.map +1 -0
  59. package/dist/components/case-studies/index.cjs +15 -15
  60. package/dist/components/case-studies/index.cjs.map +1 -1
  61. package/dist/components/case-studies/index.js +9 -9
  62. package/dist/components/case-studies/index.js.map +1 -1
  63. package/dist/components/chat/approval-request-message.d.ts.map +1 -1
  64. package/dist/components/chat/entity-cards/blog-card.d.ts.map +1 -1
  65. package/dist/components/chat/index.cjs +4 -4
  66. package/dist/components/chat/index.js +3 -3
  67. package/dist/components/chat/tool-call-blocks.d.ts.map +1 -1
  68. package/dist/components/chat/utils/compact-card-classes.d.ts +3 -3
  69. package/dist/components/chat/utils/compact-card-classes.d.ts.map +1 -1
  70. package/dist/components/contact/index.cjs +5 -5
  71. package/dist/components/contact/index.js +4 -4
  72. package/dist/components/docs/index.cjs +7 -7
  73. package/dist/components/docs/index.js +6 -6
  74. package/dist/components/embeds/index.cjs +5 -5
  75. package/dist/components/embeds/index.js +4 -4
  76. package/dist/components/faq/index.cjs +6 -6
  77. package/dist/components/faq/index.js +5 -5
  78. package/dist/components/features/index.cjs +4 -4
  79. package/dist/components/features/index.js +3 -3
  80. package/dist/components/help-center-pages/index.cjs +23 -23
  81. package/dist/components/help-center-pages/index.js +14 -14
  82. package/dist/components/index.cjs +262 -256
  83. package/dist/components/index.cjs.map +1 -1
  84. package/dist/components/index.js +117 -111
  85. package/dist/components/index.js.map +1 -1
  86. package/dist/components/msp-display.d.ts.map +1 -1
  87. package/dist/components/navigation/index.cjs +4 -4
  88. package/dist/components/navigation/index.js +3 -3
  89. package/dist/components/navigation/sticky-section-nav.d.ts.map +1 -1
  90. package/dist/components/onboarding-guides/index.cjs +8 -8
  91. package/dist/components/onboarding-guides/index.js +7 -7
  92. package/dist/components/pricing-display.d.ts +9 -9
  93. package/dist/components/related-content/index.cjs +6 -6
  94. package/dist/components/related-content/index.js +5 -5
  95. package/dist/components/tickets/index.cjs +7 -7
  96. package/dist/components/tickets/index.js +6 -6
  97. package/dist/components/toast/index.cjs +5 -5
  98. package/dist/components/toast/index.cjs.map +1 -1
  99. package/dist/components/toast/index.js +5 -5
  100. package/dist/components/toast/index.js.map +1 -1
  101. package/dist/components/ui/bullet-list.d.ts.map +1 -1
  102. package/dist/components/ui/drawer.d.ts +1 -1
  103. package/dist/components/ui/drawer.d.ts.map +1 -1
  104. package/dist/components/ui/file-manager/index.cjs +73 -73
  105. package/dist/components/ui/file-manager/index.cjs.map +1 -1
  106. package/dist/components/ui/file-manager/index.js +24 -24
  107. package/dist/components/ui/file-manager/index.js.map +1 -1
  108. package/dist/components/ui/index.cjs +4 -4
  109. package/dist/components/ui/index.js +3 -3
  110. package/dist/components/ui/markdown-editor.d.ts.map +1 -1
  111. package/dist/components/ui/square-avatar.d.ts +3 -0
  112. package/dist/components/ui/square-avatar.d.ts.map +1 -1
  113. package/dist/components/user-display.d.ts.map +1 -1
  114. package/dist/components/vendor-tag.d.ts.map +1 -1
  115. package/dist/hooks/index.cjs +2 -2
  116. package/dist/hooks/index.js +1 -1
  117. package/dist/index.cjs +4 -4
  118. package/dist/index.js +3 -3
  119. package/dist/tailwind.config.cjs +38 -5
  120. package/dist/tailwind.config.cjs.map +1 -1
  121. package/dist/tailwind.config.js +38 -5
  122. package/dist/tailwind.config.js.map +1 -1
  123. package/package.json +1 -1
  124. package/src/ODS_TOKEN_RULES.md +5 -0
  125. package/src/components/.footer.md +2 -2
  126. package/src/components/announcement-bar.tsx +1 -1
  127. package/src/components/authors/author-detail-view.tsx +3 -3
  128. package/src/components/calendar.tsx +2 -2
  129. package/src/components/case-studies/share-experience-section.tsx +5 -5
  130. package/src/components/categories-cart.tsx +6 -6
  131. package/src/components/category-card.tsx +5 -5
  132. package/src/components/chart.tsx +3 -3
  133. package/src/components/chat/approval-request-message.tsx +2 -5
  134. package/src/components/chat/chat-attachment-bar.tsx +3 -3
  135. package/src/components/chat/chat-message-enhanced.tsx +1 -1
  136. package/src/components/chat/chat-message-list.tsx +1 -1
  137. package/src/components/chat/chat-message-row.tsx +3 -3
  138. package/src/components/chat/chat-quick-action.tsx +1 -1
  139. package/src/components/chat/chat-sidebar-skeleton.tsx +1 -1
  140. package/src/components/chat/chat-sidebar.tsx +6 -6
  141. package/src/components/chat/chat-typing-indicator.tsx +1 -1
  142. package/src/components/chat/context-compaction-display.tsx +1 -1
  143. package/src/components/chat/embeddable-chat.tsx +3 -3
  144. package/src/components/chat/entity-cards/admin-content-card.tsx +5 -5
  145. package/src/components/chat/entity-cards/blog-card.tsx +5 -8
  146. package/src/components/chat/entity-cards/case-study-card.tsx +5 -5
  147. package/src/components/chat/entity-cards/chat-ticket-item.tsx +1 -1
  148. package/src/components/chat/entity-cards/customer-interview-card.tsx +9 -9
  149. package/src/components/chat/entity-cards/data-room-doc-card.tsx +2 -2
  150. package/src/components/chat/entity-cards/dispatch.tsx +1 -1
  151. package/src/components/chat/entity-cards/entity-author-card.tsx +3 -3
  152. package/src/components/chat/entity-cards/entity-portrait-card.tsx +4 -4
  153. package/src/components/chat/entity-cards/generic-entity-card.tsx +3 -3
  154. package/src/components/chat/entity-cards/github-activity-card.tsx +11 -11
  155. package/src/components/chat/entity-cards/hubspot-ticket-card.tsx +5 -5
  156. package/src/components/chat/entity-cards/investor-update-card.tsx +1 -1
  157. package/src/components/chat/entity-cards/onboarding-guide-card.tsx +12 -12
  158. package/src/components/chat/entity-cards/program-card.tsx +12 -12
  159. package/src/components/chat/entity-cards/roadmap-card.tsx +6 -6
  160. package/src/components/chat/entity-cards/roadmap-vote-button.tsx +1 -1
  161. package/src/components/chat/entity-cards/slack-message-card.tsx +4 -4
  162. package/src/components/chat/error-message-display.tsx +2 -2
  163. package/src/components/chat/mingo-info-card.tsx +2 -2
  164. package/src/components/chat/model-display.tsx +7 -7
  165. package/src/components/chat/quick-action-chip.tsx +1 -1
  166. package/src/components/chat/source-action-button.tsx +2 -2
  167. package/src/components/chat/tool-call-blocks.tsx +3 -5
  168. package/src/components/chat/utils/.chip-action-class.md +1 -1
  169. package/src/components/chat/utils/.chip-styles.md +2 -2
  170. package/src/components/chat/utils/chip-action-class.ts +1 -1
  171. package/src/components/chat/utils/chip-styles.ts +2 -2
  172. package/src/components/chat/utils/compact-card-classes.ts +3 -3
  173. package/src/components/command.tsx +3 -3
  174. package/src/components/comment-card.tsx +1 -1
  175. package/src/components/contact/contact-form.tsx +9 -9
  176. package/src/components/context-menu.tsx +5 -5
  177. package/src/components/date-time-picker.tsx +2 -2
  178. package/src/components/docs/doc-viewer.tsx +4 -4
  179. package/src/components/embeds/figma-embed.tsx +2 -2
  180. package/src/components/embeds/file-download-card.tsx +2 -2
  181. package/src/components/embeds/google-sheets-viewer.tsx +1 -1
  182. package/src/components/embeds/linkedin-embed-client.tsx +3 -3
  183. package/src/components/embeds/og-link-preview.tsx +14 -14
  184. package/src/components/embeds/pdf-viewer.tsx +1 -1
  185. package/src/components/embeds/reddit-embed-client.tsx +9 -9
  186. package/src/components/embeds/twitter-embed-client.tsx +9 -9
  187. package/src/components/empty-state.tsx +5 -5
  188. package/src/components/faq/faq-section.tsx +1 -1
  189. package/src/components/features/ai-enrich/AIEnrichSection.tsx +14 -14
  190. package/src/components/features/ai-enrich/AIRequiredBadge.tsx +5 -5
  191. package/src/components/features/ai-enrich/AIStatusIndicator.tsx +8 -8
  192. package/src/components/features/ai-enrich/AIWarningsSection.tsx +4 -4
  193. package/src/components/features/ai-enrich/ConfidenceBadge.tsx +4 -4
  194. package/src/components/features/array-entry-manager.tsx +7 -7
  195. package/src/components/features/auth-providers-list.tsx +1 -1
  196. package/src/components/features/board/ticket-card.tsx +1 -1
  197. package/src/components/features/changelog-manager.tsx +10 -10
  198. package/src/components/features/command-box.tsx +2 -2
  199. package/src/components/features/entity-summary-editor.tsx +3 -3
  200. package/src/components/features/figma-prototype-viewer.tsx +9 -9
  201. package/src/components/features/filters-dropdown.tsx +2 -2
  202. package/src/components/features/highlight-config-section.tsx +3 -3
  203. package/src/components/features/highlight-video-combined-section.tsx +2 -2
  204. package/src/components/features/highlight-video-preview.tsx +2 -2
  205. package/src/components/features/highlight-video-section.tsx +9 -9
  206. package/src/components/features/media-gallery-manager.tsx +14 -14
  207. package/src/components/features/og-editor-preview.tsx +4 -4
  208. package/src/components/features/os-type-badge-group.tsx +1 -1
  209. package/src/components/features/os-type-badge.tsx +2 -2
  210. package/src/components/features/platform-badge.tsx +4 -4
  211. package/src/components/features/policy-configuration-panel.tsx +6 -6
  212. package/src/components/features/provider-button.tsx +1 -1
  213. package/src/components/features/push-button-selector.tsx +21 -21
  214. package/src/components/features/release-media-manager.tsx +16 -16
  215. package/src/components/features/section-selector.tsx +8 -8
  216. package/src/components/features/select-button.tsx +4 -4
  217. package/src/components/features/seo-editor-preview.tsx +20 -20
  218. package/src/components/features/social-links-manager.tsx +3 -3
  219. package/src/components/features/start-with-openframe-button.tsx +3 -3
  220. package/src/components/features/status-filter-component.tsx +1 -1
  221. package/src/components/features/tags-selector.tsx +6 -6
  222. package/src/components/features/transcript-summary-editor.tsx +9 -9
  223. package/src/components/features/video-bites-strip.tsx +1 -1
  224. package/src/components/features/video-ratio-tabs.tsx +1 -1
  225. package/src/components/features/video-source-selector.tsx +7 -7
  226. package/src/components/features/video.tsx +1 -1
  227. package/src/components/features/waitlist-form.tsx +3 -3
  228. package/src/components/filter-chip.tsx +13 -13
  229. package/src/components/footer.tsx +3 -3
  230. package/src/components/form.tsx +2 -2
  231. package/src/components/hero-image-uploader.tsx +3 -3
  232. package/src/components/image-cropper.tsx +2 -2
  233. package/src/components/layout/page-container.tsx +6 -6
  234. package/src/components/layout/page-heading.tsx +1 -1
  235. package/src/components/loading/card-skeleton.tsx +2 -2
  236. package/src/components/loading/category-card-skeleton.tsx +1 -1
  237. package/src/components/loading/margin-report-skeleton.tsx +22 -22
  238. package/src/components/loading/openmsp-heartbeat.tsx +1 -1
  239. package/src/components/loading/page-layout-skeleton.tsx +83 -83
  240. package/src/components/loading/unified-skeleton.tsx +1 -1
  241. package/src/components/loading/users-grid-skeleton.tsx +2 -2
  242. package/src/components/logs-list.tsx +8 -8
  243. package/src/components/media-carousel.tsx +7 -7
  244. package/src/components/metric-value.tsx +2 -2
  245. package/src/components/msp-display.tsx +8 -2
  246. package/src/components/navigation/app-header.tsx +6 -6
  247. package/src/components/navigation/header-organization-filter.tsx +2 -2
  248. package/src/components/navigation/header.tsx +4 -4
  249. package/src/components/navigation/mobile-burger-menu.tsx +7 -7
  250. package/src/components/navigation/mobile-nav-panel.tsx +1 -1
  251. package/src/components/navigation/multi-level-navigation.tsx +7 -7
  252. package/src/components/navigation/navigation-sidebar.tsx +1 -1
  253. package/src/components/navigation/sticky-section-nav.tsx +2 -2
  254. package/src/components/onboarding-guides/onboarding-guides-catalog-view.tsx +4 -4
  255. package/src/components/pagination.tsx +2 -2
  256. package/src/components/persistent-filter-controls.tsx +1 -1
  257. package/src/components/platform/.ShellTypeBadge.md +1 -1
  258. package/src/components/platform/CveLink.tsx +1 -1
  259. package/src/components/platform/ScriptArguments.tsx +2 -2
  260. package/src/components/platform/ScriptInfoSection.tsx +5 -5
  261. package/src/components/platform/ShellTypeBadge.tsx +6 -6
  262. package/src/components/platform/SoftwareInfo.tsx +2 -2
  263. package/src/components/pricing-display.tsx +9 -9
  264. package/src/components/profile/ProfileLoadingSkeleton.tsx +6 -6
  265. package/src/components/related-content/related-content-section.tsx +3 -3
  266. package/src/components/results-count.tsx +1 -1
  267. package/src/components/shared/delivery/delivery-row.tsx +1 -1
  268. package/src/components/shared/delivery/delivery-table.tsx +1 -1
  269. package/src/components/shared/dev-section/dev-section-view.tsx +1 -1
  270. package/src/components/shared/doc-search/doc-search-result-row.tsx +2 -2
  271. package/src/components/shared/legal-document/legal-document-page.tsx +5 -5
  272. package/src/components/shared/onboarding/onboarding-step-card.tsx +1 -1
  273. package/src/components/shared/product-release/product-release-card-skeleton.tsx +3 -3
  274. package/src/components/shared/product-release/product-release-card.tsx +14 -14
  275. package/src/components/shared/product-release/release-detail-page.tsx +16 -16
  276. package/src/components/shared/roadmap/roadmap-grid.tsx +2 -2
  277. package/src/components/smooth-accordion.tsx +1 -1
  278. package/src/components/social-icon-row.tsx +1 -1
  279. package/src/components/sonner.tsx +5 -5
  280. package/src/components/steps.tsx +3 -3
  281. package/src/components/tickets/help-center-create-form.tsx +1 -1
  282. package/src/components/tickets/help-center-list.tsx +1 -1
  283. package/src/components/tickets/ticket-center.tsx +2 -2
  284. package/src/components/tickets/ticket-detail-drawer.tsx +5 -5
  285. package/src/components/tickets/ticket-open-form.tsx +6 -6
  286. package/src/components/ui/.title-content-block.md +1 -1
  287. package/src/components/ui/accordion.tsx +2 -2
  288. package/src/components/ui/actions-menu.tsx +1 -1
  289. package/src/components/ui/alert-dialog.tsx +3 -3
  290. package/src/components/ui/alert.tsx +2 -2
  291. package/src/components/ui/allowed-domains-input.tsx +3 -3
  292. package/src/components/ui/autocomplete.tsx +3 -3
  293. package/src/components/ui/badge.tsx +2 -2
  294. package/src/components/ui/brand-association-card.tsx +2 -2
  295. package/src/components/ui/breadcrumb.tsx +3 -3
  296. package/src/components/ui/bullet-list.tsx +2 -2
  297. package/src/components/ui/button/button.tsx +1 -1
  298. package/src/components/ui/card.tsx +4 -4
  299. package/src/components/ui/checkbox-with-description.tsx +1 -1
  300. package/src/components/ui/chevron-button.tsx +1 -1
  301. package/src/components/ui/content-loader.tsx +16 -16
  302. package/src/components/ui/cursor-pagination.tsx +1 -1
  303. package/src/components/ui/date-picker.tsx +2 -2
  304. package/src/components/ui/device-card-compact.tsx +2 -2
  305. package/src/components/ui/device-card.tsx +3 -3
  306. package/src/components/ui/dialog.tsx +3 -3
  307. package/src/components/ui/drawer.tsx +4 -4
  308. package/src/components/ui/dropdown-menu.tsx +6 -6
  309. package/src/components/ui/error-state.tsx +9 -9
  310. package/src/components/ui/fade-preview.tsx +1 -1
  311. package/src/components/ui/field-wrapper.tsx +1 -1
  312. package/src/components/ui/file-manager/file-manager-breadcrumb.tsx +2 -2
  313. package/src/components/ui/file-manager/file-manager-empty.tsx +3 -3
  314. package/src/components/ui/file-manager/file-manager-skeleton.tsx +4 -4
  315. package/src/components/ui/file-manager/file-manager-table-row.tsx +7 -7
  316. package/src/components/ui/file-manager/file-manager-table.tsx +8 -8
  317. package/src/components/ui/file-upload.tsx +9 -9
  318. package/src/components/ui/filter-pill-row.tsx +1 -1
  319. package/src/components/ui/floating-tooltip.tsx +1 -1
  320. package/src/components/ui/highlight-card.tsx +1 -1
  321. package/src/components/ui/hover-dropdown.tsx +1 -1
  322. package/src/components/ui/image-gallery-modal.tsx +1 -1
  323. package/src/components/ui/info-row.tsx +1 -1
  324. package/src/components/ui/input.tsx +1 -1
  325. package/src/components/ui/label.tsx +5 -5
  326. package/src/components/ui/markdown-editor.tsx +4 -5
  327. package/src/components/ui/menubar.tsx +7 -7
  328. package/src/components/ui/modal-v2.tsx +1 -1
  329. package/src/components/ui/modal.tsx +1 -1
  330. package/src/components/ui/more-actions-menu.tsx +1 -1
  331. package/src/components/ui/navigation-menu.tsx +1 -1
  332. package/src/components/ui/organization-card.tsx +8 -8
  333. package/src/components/ui/page-loader.tsx +6 -6
  334. package/src/components/ui/phone-input.tsx +1 -1
  335. package/src/components/ui/progress-bar.tsx +5 -5
  336. package/src/components/ui/query-report-table/.query-report-table-header.md +1 -1
  337. package/src/components/ui/query-report-table/query-report-table-header.tsx +1 -1
  338. package/src/components/ui/query-report-table/query-report-table-row.tsx +2 -2
  339. package/src/components/ui/query-report-table/query-report-table.tsx +1 -1
  340. package/src/components/ui/release-changelog-section.tsx +2 -2
  341. package/src/components/ui/rich-markdown-renderer.tsx +6 -6
  342. package/src/components/ui/search-input.tsx +7 -7
  343. package/src/components/ui/select.tsx +1 -1
  344. package/src/components/ui/service-card.tsx +4 -4
  345. package/src/components/ui/sheet.tsx +3 -3
  346. package/src/components/ui/simple-markdown-renderer.tsx +4 -4
  347. package/src/components/ui/square-avatar.tsx +9 -5
  348. package/src/components/ui/status-badge.tsx +11 -11
  349. package/src/components/ui/status-indicator.tsx +6 -6
  350. package/src/components/ui/tab-content.tsx +1 -1
  351. package/src/components/ui/tab-navigation.tsx +2 -2
  352. package/src/components/ui/table/table-column-filter-dropdown.tsx +1 -1
  353. package/src/components/ui/table/table-description-cell.tsx +1 -1
  354. package/src/components/ui/table/table-timestamp-cell.tsx +1 -1
  355. package/src/components/ui/table/table.tsx +2 -2
  356. package/src/components/ui/tabs.tsx +1 -1
  357. package/src/components/ui/tag-search-input.tsx +1 -1
  358. package/src/components/ui/tag.tsx +23 -23
  359. package/src/components/ui/tags-input.tsx +2 -2
  360. package/src/components/ui/ticket-status-tag.tsx +1 -1
  361. package/src/components/ui/toaster.tsx +8 -8
  362. package/src/components/ui/toggle.tsx +1 -1
  363. package/src/components/ui/tooltip.tsx +1 -1
  364. package/src/components/user-display.tsx +12 -6
  365. package/src/components/user-summary-stub.tsx +4 -4
  366. package/src/components/vendor-display-button.tsx +2 -2
  367. package/src/components/vendor-icon.tsx +1 -1
  368. package/src/components/vendor-tag.tsx +9 -10
  369. package/src/components/yes-no-display.tsx +3 -3
  370. package/src/styles/ods-colors.css +2 -0
  371. package/tailwind.config.ts +49 -4
  372. package/dist/chunk-2ELBNZJ3.js.map +0 -1
  373. package/dist/chunk-3WJQL4DN.cjs.map +0 -1
  374. package/dist/chunk-4ACSUJ7Q.js.map +0 -1
  375. package/dist/chunk-7WM77CSW.js.map +0 -1
  376. package/dist/chunk-COMBYYQY.js.map +0 -1
  377. package/dist/chunk-EGRZHR7J.js.map +0 -1
  378. package/dist/chunk-F7YVI54P.js.map +0 -1
  379. package/dist/chunk-G5FALXNO.js.map +0 -1
  380. package/dist/chunk-HTVVXVJL.cjs.map +0 -1
  381. package/dist/chunk-IAN7GUIV.cjs.map +0 -1
  382. package/dist/chunk-IMK6RUEC.cjs.map +0 -1
  383. package/dist/chunk-M6QGB6DC.cjs.map +0 -1
  384. package/dist/chunk-N2TJ3HAM.cjs.map +0 -1
  385. package/dist/chunk-NQQ4NLUT.js.map +0 -1
  386. package/dist/chunk-P7PISHM5.js.map +0 -1
  387. package/dist/chunk-PBTY7AH5.js.map +0 -1
  388. package/dist/chunk-R46QEE3R.cjs.map +0 -1
  389. package/dist/chunk-RQQZF6G6.cjs.map +0 -1
  390. package/dist/chunk-RVWC4P3H.js.map +0 -1
  391. package/dist/chunk-VWGF6IFR.cjs.map +0 -1
  392. package/dist/chunk-WAGTZVQN.js.map +0 -1
  393. package/dist/chunk-WZ6TCAYQ.cjs.map +0 -1
  394. package/dist/components/accordion.d.ts +0 -8
  395. package/dist/components/accordion.d.ts.map +0 -1
  396. package/dist/components/alert-dialog.d.ts +0 -21
  397. package/dist/components/alert-dialog.d.ts.map +0 -1
  398. package/dist/components/alert.d.ts +0 -9
  399. package/dist/components/alert.d.ts.map +0 -1
  400. package/dist/components/badge.d.ts +0 -10
  401. package/dist/components/badge.d.ts.map +0 -1
  402. package/dist/components/breadcrumb.d.ts +0 -20
  403. package/dist/components/breadcrumb.d.ts.map +0 -1
  404. package/dist/components/chevron-button.d.ts +0 -14
  405. package/dist/components/chevron-button.d.ts.map +0 -1
  406. package/dist/components/dialog.d.ts +0 -29
  407. package/dist/components/dialog.d.ts.map +0 -1
  408. package/dist/components/dropdown-menu.d.ts +0 -28
  409. package/dist/components/dropdown-menu.d.ts.map +0 -1
  410. package/dist/components/input.d.ts +0 -8
  411. package/dist/components/input.d.ts.map +0 -1
  412. package/dist/components/label.d.ts +0 -6
  413. package/dist/components/label.d.ts.map +0 -1
  414. package/dist/components/menubar.d.ts +0 -34
  415. package/dist/components/menubar.d.ts.map +0 -1
  416. package/dist/components/navigation-menu.d.ts +0 -13
  417. package/dist/components/navigation-menu.d.ts.map +0 -1
  418. package/dist/components/select.d.ts +0 -14
  419. package/dist/components/select.d.ts.map +0 -1
  420. package/dist/components/sidebar.d.ts +0 -67
  421. package/dist/components/sidebar.d.ts.map +0 -1
  422. package/dist/components/square-avatar.d.ts +0 -21
  423. package/dist/components/square-avatar.d.ts.map +0 -1
  424. package/dist/components/table.d.ts +0 -11
  425. package/dist/components/table.d.ts.map +0 -1
  426. package/dist/components/tabs.d.ts +0 -18
  427. package/dist/components/tabs.d.ts.map +0 -1
  428. package/dist/components/toggle.d.ts +0 -13
  429. package/dist/components/toggle.d.ts.map +0 -1
  430. package/src/components/.accordion.md +0 -42
  431. package/src/components/.alert-dialog.md +0 -58
  432. package/src/components/.alert.md +0 -43
  433. package/src/components/.badge.md +0 -40
  434. package/src/components/.breadcrumb.md +0 -54
  435. package/src/components/.chevron-button.md +0 -46
  436. package/src/components/.dialog.md +0 -60
  437. package/src/components/.dropdown-menu.md +0 -51
  438. package/src/components/.input.md +0 -40
  439. package/src/components/.label.md +0 -41
  440. package/src/components/.menubar.md +0 -49
  441. package/src/components/.navigation-menu.md +0 -44
  442. package/src/components/.select.md +0 -54
  443. package/src/components/.sidebar.md +0 -58
  444. package/src/components/.square-avatar.md +0 -42
  445. package/src/components/.table.md +0 -51
  446. package/src/components/.tabs.md +0 -38
  447. package/src/components/.toggle.md +0 -49
  448. package/src/components/accordion.tsx +0 -56
  449. package/src/components/alert-dialog.tsx +0 -141
  450. package/src/components/alert.tsx +0 -59
  451. package/src/components/badge.tsx +0 -30
  452. package/src/components/breadcrumb.tsx +0 -115
  453. package/src/components/chevron-button.tsx +0 -68
  454. package/src/components/dialog.tsx +0 -150
  455. package/src/components/dropdown-menu.tsx +0 -200
  456. package/src/components/input.tsx +0 -39
  457. package/src/components/label.tsx +0 -19
  458. package/src/components/menubar.tsx +0 -236
  459. package/src/components/navigation-menu.tsx +0 -128
  460. package/src/components/select.tsx +0 -160
  461. package/src/components/sidebar.tsx +0 -764
  462. package/src/components/square-avatar.tsx +0 -61
  463. package/src/components/table.tsx +0 -72
  464. package/src/components/tabs.tsx +0 -65
  465. package/src/components/toggle.tsx +0 -45
  466. /package/dist/{chunk-QXYOGJQJ.js.map → chunk-7KDR5P23.js.map} +0 -0
  467. /package/dist/{chunk-PEIR7D25.js.map → chunk-7KNOHGMI.js.map} +0 -0
@@ -70,7 +70,7 @@ export function VendorTag({
70
70
  className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0"
71
71
  style={accentColor ? { backgroundColor: accentColor } : undefined}
72
72
  >
73
- <OpenSourceIcon width={10} height={10} className="text-[#1A1A1A]" />
73
+ <OpenSourceIcon width={10} height={10} className="text-ods-text-on-accent" />
74
74
  </div>
75
75
  )
76
76
  }
@@ -125,7 +125,7 @@ export function VendorTag({
125
125
  text: text || "Free",
126
126
  icon: (
127
127
  <div className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0">
128
- <span className="text-[#1A1A1A] text-[8px] font-bold">$</span>
128
+ <span className="text-ods-text-on-accent text-[8px] font-bold">$</span>
129
129
  </div>
130
130
  )
131
131
  }
@@ -134,7 +134,7 @@ export function VendorTag({
134
134
  text: text || "Freemium",
135
135
  icon: (
136
136
  <div className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0">
137
- <span className="text-[#1A1A1A] text-[8px] font-bold">$</span>
137
+ <span className="text-ods-text-on-accent text-[8px] font-bold">$</span>
138
138
  </div>
139
139
  )
140
140
  }
@@ -152,7 +152,7 @@ export function VendorTag({
152
152
  text: text || "Enterprise",
153
153
  icon: (
154
154
  <div className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0">
155
- <span className="text-[#1A1A1A] text-[8px] font-bold">E</span>
155
+ <span className="text-ods-text-on-accent text-[8px] font-bold">E</span>
156
156
  </div>
157
157
  )
158
158
  }
@@ -161,7 +161,7 @@ export function VendorTag({
161
161
  text: text || "Recommended",
162
162
  icon: (
163
163
  <div className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0">
164
- <span className="text-[#1A1A1A] text-[8px] font-bold">★</span>
164
+ <span className="text-ods-text-on-accent text-[8px] font-bold">★</span>
165
165
  </div>
166
166
  )
167
167
  }
@@ -174,7 +174,7 @@ export function VendorTag({
174
174
  text: "Open Source",
175
175
  icon: (
176
176
  <div className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0">
177
- <OpenSourceIcon width={10} height={10} className="text-[#1A1A1A]" />
177
+ <OpenSourceIcon width={10} height={10} className="text-ods-text-on-accent" />
178
178
  </div>
179
179
  )
180
180
  }
@@ -198,7 +198,7 @@ export function VendorTag({
198
198
  text: text || "Classification",
199
199
  icon: (
200
200
  <div className="w-4 h-4 bg-ods-accent rounded-sm flex items-center justify-center flex-shrink-0">
201
- <span className="text-[#1A1A1A] text-[8px] font-bold">C</span>
201
+ <span className="text-ods-text-on-accent text-[8px] font-bold">C</span>
202
202
  </div>
203
203
  )
204
204
  }
@@ -222,9 +222,8 @@ export function VendorTag({
222
222
  <div className={cn(baseClasses, className, hidden && "invisible")}>
223
223
  {icon}
224
224
  <span className={cn(
225
- "font-mono font-semibold uppercase",
226
- textColor ? textColor : "text-ods-text-primary",
227
- size === 'sm' ? "text-[10px]" : "text-xs"
225
+ "text-h5 font-semibold",
226
+ textColor ? textColor : "text-ods-text-primary"
228
227
  )}>
229
228
  {displayText}
230
229
  </span>
@@ -22,7 +22,7 @@ export function YesNoDisplay({
22
22
  return (
23
23
  <div className={`flex items-center gap-2 ${className}`}>
24
24
  <LucideCheckCircleIcon className="h-6 w-6" />
25
- <span className="text-ods-text-primary text-[16px]">{customText}</span>
25
+ <span className="text-ods-text-primary text-h6">{customText}</span>
26
26
  </div>
27
27
  )
28
28
  }
@@ -32,7 +32,7 @@ export function YesNoDisplay({
32
32
  return (
33
33
  <div className={`flex items-center gap-2 ${className}`}>
34
34
  <LucideCheckCircleIcon className="h-6 w-6" />
35
- <span className="text-ods-text-primary text-[16px]">{yesText}</span>
35
+ <span className="text-ods-text-primary text-h6">{yesText}</span>
36
36
  </div>
37
37
  )
38
38
  }
@@ -40,7 +40,7 @@ export function YesNoDisplay({
40
40
  return (
41
41
  <div className={`flex items-center gap-2 ${className}`}>
42
42
  <XCircleIcon className="h-6 w-6" />
43
- <span className="text-ods-text-secondary text-[16px]">{noText}</span>
43
+ <span className="text-ods-text-secondary text-h6">{noText}</span>
44
44
  </div>
45
45
  )
46
46
  }
@@ -256,6 +256,8 @@
256
256
  --color-bg-overlay: rgba(33, 33, 33, 0.8);
257
257
  --color-bg-skeleton: var(--ods-system-greys-black);
258
258
  --color-bg-surface: var(--ods-system-greys-soft-grey);
259
+ --color-bg-surface-hover: var(--ods-system-greys-soft-grey-hover);
260
+ --color-bg-surface-active: var(--ods-system-greys-soft-grey-action);
259
261
  --color-bg-inverted: var(--ods-system-greys-white);
260
262
  --color-bg-backdrop: rgba(0, 0, 0, 0.6);
261
263
  /* Card layers (consumed by platform blocks; theme owns the value) */
@@ -46,9 +46,37 @@ const odsTypographyPlugin = plugin(({ addUtilities }) => {
46
46
  fontSize: 'var(--font-size-h6-caption)',
47
47
  lineHeight: 'var(--font-line-space-h6-caption)',
48
48
  },
49
+ // Monospace body/code text (commands, ids, paths, code blocks): Azeret Mono
50
+ // at the h6 responsive scale, no transform, neutral letter-spacing (unlike
51
+ // text-h5's uppercase -0.02em label styling).
52
+ '.text-code': {
53
+ fontFamily: 'var(--font-family-heading)',
54
+ fontWeight: 'var(--font-weight-medium)',
55
+ fontSize: 'var(--font-size-h6-caption)',
56
+ lineHeight: 'var(--font-line-space-h6-caption)',
57
+ },
49
58
  })
50
59
  })
51
60
 
61
+ /**
62
+ * Make Tailwind opacity modifiers (`bg-ods-error/10`, `hover:bg-ods-accent/90`, …)
63
+ * actually work on var()-based ODS tokens. Without `<alpha-value>` in the color
64
+ * definition Tailwind v3 silently generates NOTHING for `ods-*\/N` classes — the
65
+ * element loses that declaration entirely. `color-mix` keeps un-suffixed classes
66
+ * visually identical (a 100% mix is the color itself) while letting the modifier
67
+ * scale the alpha.
68
+ */
69
+ const withAlphaValue = (color: string) => `color-mix(in srgb, ${color} calc(<alpha-value> * 100%), transparent)`
70
+
71
+ type ColorTree = { [key: string]: string | ColorTree }
72
+ const withAlphaSupport = (tree: ColorTree): ColorTree =>
73
+ Object.fromEntries(
74
+ Object.entries(tree).map(([key, value]) => [
75
+ key,
76
+ typeof value === 'string' ? withAlphaValue(value) : withAlphaSupport(value),
77
+ ]),
78
+ )
79
+
52
80
  const config: Config = {
53
81
  content: [
54
82
  "./src/**/*.{js,ts,jsx,tsx}",
@@ -110,7 +138,7 @@ const config: Config = {
110
138
  // ODS (Open Design System) COLORS
111
139
  // =================================================
112
140
  // Single nested structure: generates bg-ods-*, text-ods-*, border-ods-* utilities
113
- ods: {
141
+ ods: withAlphaSupport({
114
142
  // Backgrounds
115
143
  bg: "var(--color-bg)",
116
144
  card: "var(--color-bg-card)",
@@ -119,6 +147,8 @@ const config: Config = {
119
147
  "bg-hover": "var(--color-bg-hover)",
120
148
  "bg-active": "var(--color-bg-active)",
121
149
  "bg-surface": "var(--color-bg-surface)",
150
+ "bg-surface-hover": "var(--color-bg-surface-hover)",
151
+ "bg-surface-active": "var(--color-bg-surface-active)",
122
152
  "card-hover": "var(--color-bg-hover)",
123
153
  divider: "var(--color-divider)",
124
154
 
@@ -196,12 +226,27 @@ const config: Config = {
196
226
 
197
227
  // Brand colors (theme-independent)
198
228
  flamingo: {
199
- pink: "var(--ods-flamingo-pink-base)",
200
- cyan: "var(--ods-flamingo-cyan-base)",
229
+ pink: {
230
+ DEFAULT: "var(--ods-flamingo-pink-base)",
231
+ hover: "var(--ods-flamingo-pink-hover)",
232
+ secondary: "var(--ods-flamingo-pink-secondary)",
233
+ "secondary-hover": "var(--ods-flamingo-pink-secondary-hover)",
234
+ "secondary-active": "var(--ods-flamingo-pink-secondary-action)",
235
+ },
236
+ cyan: {
237
+ DEFAULT: "var(--ods-flamingo-cyan-base)",
238
+ hover: "var(--ods-flamingo-cyan-hover)",
239
+ secondary: "var(--ods-flamingo-cyan-secondary)",
240
+ "secondary-hover": "var(--ods-flamingo-cyan-secondary-hover)",
241
+ "secondary-active": "var(--ods-flamingo-cyan-secondary-action)",
242
+ },
201
243
  },
202
244
  "open-yellow": {
203
245
  DEFAULT: "var(--ods-open-yellow-base)",
204
246
  secondary: "var(--ods-open-yellow-secondary)",
247
+ light: "var(--ods-open-yellow-light)",
248
+ "light-hover": "var(--ods-open-yellow-light-hover)",
249
+ "light-action": "var(--ods-open-yellow-light-action)",
205
250
  },
206
251
 
207
252
  // Attention tokens (ods-colors.css). Components reference these BY
@@ -231,7 +276,7 @@ const config: Config = {
231
276
 
232
277
  // Adaptive platform color
233
278
  current: "var(--ods-current)",
234
- },
279
+ }),
235
280
  },
236
281
  // Custom breakpoints (aligned with ODS responsive tokens from Figma)
237
282
  screens: {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/embeds/pdf-viewer.tsx","../src/components/embeds/google-sheets-viewer.tsx","../src/components/embeds/file-download-card.tsx"],"sourcesContent":["\"use client\"\n\nimport React from 'react'\nimport { Button } from '../ui'\nimport { Download, Eye } from 'lucide-react'\nimport { AdobePdfIcon } from '../icons-v2-generated'\nimport { EmbedIframe } from './embed-iframe'\n\nexport interface PdfViewerProps {\n src: string\n fileName?: string\n onPreview?: () => void\n onDownload?: () => void\n height?: string\n}\n\nexport function PdfViewer({ src, fileName, onPreview, onDownload, height }: PdfViewerProps) {\n const displayName = fileName || 'PDF Document'\n\n if (!src) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <AdobePdfIcon className=\"w-16 h-16 text-ods-text-secondary mb-4\" />\n <p className=\"text-ods-text-secondary\">PDF file not available</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <AdobePdfIcon className=\"w-5 h-5 shrink-0\" />\n <h2 className=\"text-xl font-semibold text-ods-text-primary truncate\">{displayName}</h2>\n </div>\n <div className=\"flex items-center gap-2 w-full sm:w-auto\">\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={onPreview ? undefined : src}\n openInNewTab={!onPreview}\n onClick={onPreview}\n leftIcon={<Eye className=\"w-4 h-4\" />}\n className=\"flex-1 sm:flex-initial\"\n >\n Preview\n </Button>\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={onDownload ? undefined : src}\n openInNewTab={!onDownload}\n onClick={onDownload}\n leftIcon={<Download className=\"w-4 h-4\" />}\n className=\"flex-1 sm:flex-initial\"\n >\n Download\n </Button>\n </div>\n </div>\n <EmbedIframe src={src} title={displayName} height={height} />\n </div>\n )\n}\n","\"use client\"\n\nimport React from 'react'\nimport { Button } from '../ui'\nimport { ExternalLink } from 'lucide-react'\nimport { GoogleSheetsIcon } from '../icons-v2-generated'\nimport { EmbedIframe } from './embed-iframe'\nimport { toGoogleSheetsEmbedUrl, toGoogleSheetsOriginalUrl } from '../../utils/embed-url-converters'\n\nexport interface GoogleSheetsViewerProps {\n externalUrl: string\n fileName?: string\n height?: string\n}\n\nexport function GoogleSheetsViewer({ externalUrl, fileName, height }: GoogleSheetsViewerProps) {\n const displayName = fileName || 'Google Sheet'\n\n if (!externalUrl) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <GoogleSheetsIcon className=\"w-16 h-16 text-ods-text-secondary mb-4\" />\n <p className=\"text-ods-text-secondary\">Google Sheet URL not configured</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <GoogleSheetsIcon className=\"w-5 h-5 shrink-0\" />\n <h2 className=\"text-xl font-semibold text-ods-text-primary truncate\">{displayName}</h2>\n </div>\n <Button\n variant=\"outline\"\n size=\"small-legacy\"\n href={toGoogleSheetsOriginalUrl(externalUrl)}\n openInNewTab\n leftIcon={<GoogleSheetsIcon className=\"w-4 h-4\" />}\n rightIcon={<ExternalLink className=\"w-4 h-4\" />}\n className=\"w-full sm:w-auto\"\n >\n Open in Google Sheets\n </Button>\n </div>\n <EmbedIframe\n src={toGoogleSheetsEmbedUrl(externalUrl)}\n title={displayName}\n height={height}\n />\n </div>\n )\n}\n","import React from 'react'\nimport { Button } from '../ui'\nimport { FileText, Download } from 'lucide-react'\nimport { formatFileSize } from '../../utils'\n\nexport interface FileDownloadCardProps {\n fileName?: string\n mimeType?: string\n fileSize?: number\n fileUrl?: string\n}\n\n/**\n * Generic downloadable-file card for the `file` document type. Used by\n * `<DocsHubPage>`'s default `documentTypeRenderers.file`. Embedders can\n * override the default by passing their own `file` renderer.\n *\n * When `fileUrl` is missing, the Download button is omitted (the card still\n * renders the filename + type + size so the user knows what they were\n * about to download).\n */\nexport function FileDownloadCard({\n fileName,\n mimeType,\n fileSize,\n fileUrl,\n}: FileDownloadCardProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-16\">\n <div className=\"bg-ods-card border border-ods-border rounded-xl p-8 max-w-md w-full text-center space-y-4\">\n <FileText className=\"w-16 h-16 text-ods-text-secondary mx-auto\" />\n <div>\n <h3 className=\"text-lg font-semibold text-ods-text-primary\">\n {fileName || 'File'}\n </h3>\n <div className=\"flex items-center justify-center gap-3 mt-2 text-sm text-ods-text-secondary\">\n {mimeType && <span>{mimeType}</span>}\n {typeof fileSize === 'number' && <span>{formatFileSize(fileSize)}</span>}\n </div>\n </div>\n {fileUrl && (\n <Button\n variant=\"accent\"\n href={fileUrl}\n openInNewTab\n leftIcon={<Download className=\"w-4 h-4\" />}\n >\n Download File\n </Button>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","jsxs","Download","jsx","jsxs","Download"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-3WJQL4DN.cjs","../src/components/unified-pagination.tsx","../src/components/empty-state.tsx","../src/components/shared/dev-section/dev-section-view.tsx","../src/components/shared/dev-section/dev-section-page.tsx","../src/components/shared/dev-section/dev-card-row.tsx","../src/components/shared/delivery/delivery-row.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-3WJQL4DN.cjs","sourcesContent":[null,"\"use client\"\n\nimport { useRouter, useSearchParams, usePathname } from \"../embed-shims/next-navigation\"\nimport { Pagination } from \"./pagination\"\n\ninterface UnifiedPaginationProps {\n currentPage: number\n totalPages: number\n onPageChange?: (page: number) => void\n className?: string\n}\n\nexport function UnifiedPagination({ \n currentPage, \n totalPages, \n onPageChange,\n className = \"mt-8 flex justify-center w-full\"\n}: UnifiedPaginationProps) {\n const router = useRouter()\n const searchParams = useSearchParams()\n const pathname = usePathname()\n\n const handlePageChange = (page: number) => {\n // Preserve current scroll position\n const currentScrollY = window.scrollY\n \n // Call the callback to update local state (prevents reload)\n if (onPageChange) {\n onPageChange(page)\n }\n \n // Update URL for bookmarking without navigation\n const params = new URLSearchParams(searchParams.toString())\n params.set(\"page\", page.toString())\n \n // Update URL without navigation (for bookmarking support)\n const newUrl = `${pathname}?${params.toString()}`\n window.history.replaceState(null, '', newUrl)\n \n // Restore scroll position after a brief delay to allow content to render\n setTimeout(() => {\n window.scrollTo({\n top: currentScrollY,\n behavior: 'instant' // Instant to prevent any scroll animation\n })\n }, 0)\n }\n\n // Don't render pagination if there's only one page\n if (totalPages <= 1) return null\n\n return (\n <div className={className}>\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n onPageChange={handlePageChange}\n />\n </div>\n )\n} ","\"use client\";\n\nimport { Search, FileText, Package } from \"lucide-react\"\nimport { Button } from \"./ui/button\"\nimport { useRouter } from \"../embed-shims/next-navigation\"\n\nexport interface EmptyStateProps {\n type: 'vendors' | 'posts' | 'search' | 'generic'\n title?: string\n description?: string\n showBackButton?: boolean\n onGoBack?: () => void\n backButtonText?: string\n // New CTA properties\n showCTA?: boolean\n ctaText?: string\n onCtaClick?: () => void\n ctaVariant?: 'primary' | 'secondary'\n}\n\nexport function EmptyState({\n type,\n title,\n description,\n showBackButton = false,\n onGoBack,\n backButtonText = \"Go Back\",\n showCTA = true,\n ctaText,\n onCtaClick,\n ctaVariant = 'primary'\n}: EmptyStateProps) {\n const router = useRouter()\n\n // Default content based on type\n const getDefaultContent = () => {\n switch (type) {\n case 'vendors':\n return {\n icon: <Package className=\"w-full h-full\" />,\n title: \"No vendors found\",\n description: \"We couldn't find any vendors matching your criteria. Try adjusting your filters or search terms.\"\n }\n case 'posts':\n return {\n icon: <FileText className=\"w-full h-full\" />,\n title: \"No articles found\",\n description: \"We couldn't find any articles matching your criteria. Try different categories, tags, or search terms.\"\n }\n case 'search':\n return {\n icon: <Search className=\"w-full h-full\" />,\n title: \"No results found\",\n description: \"Your search didn't return any results. Try different keywords or browse our categories.\"\n }\n default:\n return {\n icon: <Search className=\"w-full h-full\" />,\n title: \"Nothing found\",\n description: \"We couldn't find what you're looking for. Try adjusting your search or filters.\"\n }\n }\n }\n\n // Smart CTA logic based on context\n const getSmartCTA = () => {\n // If custom CTA is provided, use it\n if (ctaText && onCtaClick) {\n return {\n text: ctaText,\n action: onCtaClick\n }\n }\n\n // Check if we're on the client side\n const isClient = typeof window !== 'undefined'\n const currentPath = isClient ? window.location.pathname : ''\n\n // Smart defaults based on type and context\n switch (type) {\n case 'search':\n return {\n text: \"Reset Filters\",\n action: () => {\n if (isClient) {\n // Try to reset search by clearing URL params and refreshing\n const url = new URL(window.location.href)\n url.search = ''\n router.push(url.pathname)\n }\n }\n }\n case 'posts':\n // If we're on blog/community pages, reset blog filters\n if (currentPath.includes('/blog')) {\n return {\n text: \"Reset Filters\",\n action: () => {\n if (isClient) {\n // Reset blog search and filters by clearing URL params\n const url = new URL(window.location.href)\n url.search = ''\n router.push(url.pathname)\n }\n }\n }\n } else if (currentPath.includes('/profile')) {\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n }\n return {\n text: \"View All Posts\",\n action: () => router.push('/blog')\n }\n case 'vendors':\n // If we're in profile or other pages, direct to main content\n if (currentPath.includes('/profile')) {\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n } else if (currentPath.includes('/vendors') || currentPath.includes('/margin-increase/compare')) {\n return {\n text: \"Reset Filters\",\n action: () => {\n if (isClient) {\n // Reset vendor search and filters by clearing URL params\n const url = new URL(window.location.href)\n url.search = ''\n router.push(url.pathname)\n }\n }\n }\n }\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n default:\n return {\n text: \"Browse Vendors\",\n action: () => router.push('/vendors')\n }\n }\n }\n\n const defaultContent = getDefaultContent()\n const displayTitle = title || defaultContent.title\n const displayDescription = description || defaultContent.description\n const smartCTA = getSmartCTA()\n\n return (\n <div className=\"flex flex-col items-center justify-center py-6 md:py-16 px-6 text-center\">\n {/* Icon */}\n <div className=\"mb-3 md:mb-6 flex items-center justify-center\">\n <div className=\"rounded-full bg-ods-card p-3 md:p-6 border border-ods-border\">\n <div className=\"w-8 h-8 md:w-16 md:h-16 text-ods-text-secondary flex items-center justify-center\">\n {defaultContent.icon}\n </div>\n </div>\n </div>\n\n {/* Title */}\n <h2 className=\"mb-2 md:mb-3 text-lg md:text-xl font-semibold font-['DM_Sans'] text-ods-text-primary tracking-[-0.02em]\">\n {displayTitle}\n </h2>\n\n {/* Description */}\n <p className=\"mb-4 md:mb-8 max-w-md text-sm font-medium font-['DM_Sans'] text-ods-text-secondary leading-[1.43em]\">\n {displayDescription}\n </p>\n\n {/* Smart CTA Button */}\n {showCTA && smartCTA && (\n <div className=\"w-full max-w-xs mb-3\">\n <Button\n onClick={smartCTA.action}\n className={ctaVariant === 'primary'\n ? \"w-full bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover transition-all duration-150 font-['DM_Sans'] font-medium\"\n : \"w-full bg-transparent border border-ods-border text-ods-text-primary hover:border-ods-accent hover:text-ods-accent transition-all duration-150 font-['DM_Sans'] font-medium\"\n }\n >\n {smartCTA.text}\n </Button>\n </div>\n )}\n\n {/* Optional Back Button */}\n {showBackButton && onGoBack && (\n <div className=\"w-full max-w-xs\">\n <Button\n onClick={onGoBack}\n variant=\"outline\"\n className=\"w-full transition-all duration-150 font-['DM_Sans'] font-medium\"\n >\n {backButtonText}\n </Button>\n </div>\n )}\n </div>\n )\n} ","'use client';\n\n/**\n * DevSectionView — the canonical chrome for ANY dev-center section\n * (Roadmap / Delivery / Releases). One component, used in BOTH:\n *\n * - tabbed `/roadmap-and-releases` (compact title mode, no `hero`)\n * - full-page `/roadmap`, `/bug-fixes-and-enhancements`, `/releases`\n * (hero mode with icon + description + back link)\n *\n * Owns: title rendering, the inline search input, the filter pill row,\n * and the URL-param wiring that connects both. The list `children`\n * receive a clean URL contract — they read `?<paramKey>=...` via\n * `useSearchParams()` and refetch on change. No duplicated controls.\n */\n\nimport type { ReactNode } from 'react';\nimport { useState, useEffect } from 'react';\nimport { useRouter, useSearchParams, usePathname } from '../../../embed-shims';\nimport { SearchInput } from '../../ui';\nimport { StatusFilterComponent } from '../../features';\nimport {\n OPENFRAME_DEV_SECTIONS,\n type OpenframeDevSectionKey,\n} from '../../../utils/dev-sections/openframe-dev-sections';\n\nexport interface DevSectionViewProps {\n /** Which section to render — drives title, search, and filter\n * config via the `OPENFRAME_DEV_SECTIONS` registry. */\n sectionKey: OpenframeDevSectionKey;\n /** When set, renders the rich page-level hero (icon + h1 + description).\n * Omit for the compact tab-context heading. */\n hero?: {\n /** Pre-rendered icon JSX. Server components render the icon themselves\n * and pass the element here — function references can't cross the\n * server→client boundary, but React elements can. */\n icon: ReactNode;\n /** Hero title. Falls back to `OPENFRAME_DEV_SECTIONS[sectionKey].hero.title`\n * when omitted, so embedders can override the (OpenFrame-specific) default\n * copy without forking the registry. */\n title?: string;\n description: string;\n };\n /** Optional slot rendered BETWEEN the hero and the search/filter\n * controls. Use this for an entry-action surface that should sit\n * above the list (e.g. the Help Center's \"Open a new ticket\" form).\n * The slot is wrapped in the same `gap-10` flex column so spacing\n * matches the surrounding chrome — callers should NOT add their\n * own top/bottom margin. Renders `null` (no DOM) when omitted. */\n preControls?: ReactNode;\n /** The page-specific list body. Reads URL params written by this\n * component (search input + filter pills). */\n children: ReactNode;\n /** Render this component's own title heading (hero or compact `h2`). Default\n * `true` — the tab context renders the compact heading itself. Pass `false`\n * when the host already renders the title elsewhere (e.g. `DevSectionPage`\n * routes it through the unified `PageLayout` `TitleBlock`): then only the\n * search + filter controls + list render, with no duplicate heading. */\n showHeading?: boolean;\n}\n\nexport function DevSectionView({ sectionKey, hero, preControls, children, showHeading = true }: DevSectionViewProps) {\n const section = OPENFRAME_DEV_SECTIONS[sectionKey];\n const router = useRouter();\n const pathname = usePathname();\n const searchParams = useSearchParams();\n\n const search = section.search;\n const filter = section.filter;\n\n const currentSearch = search ? searchParams.get(search.paramKey) || '' : '';\n const currentFilterValue = filter\n ? searchParams.get(filter.paramKey) || filter.defaultValue\n : '';\n\n // Controlled search-input state — input commits to the URL only on\n // Enter (not on every keystroke), preserving the legacy behavior.\n // Lazy init from URL avoids a brief flash of stale value on first\n // paint after URL-driven re-render (e.g. tab switch).\n const [searchValue, setSearchValue] = useState(() => currentSearch);\n useEffect(() => {\n setSearchValue(currentSearch);\n }, [currentSearch]);\n\n const handleSearchSubmit = (value: string) => {\n if (!search) return;\n const params = new URLSearchParams(searchParams.toString());\n if (value.trim()) params.set(search.paramKey, value.trim());\n else params.delete(search.paramKey);\n router.replace(`${pathname}?${params.toString()}`, { scroll: false });\n };\n\n const handleFilterChange = (value: string) => {\n if (!filter) return;\n const params = new URLSearchParams(searchParams.toString());\n if (value === filter.defaultValue) params.delete(filter.paramKey);\n else params.set(filter.paramKey, value);\n router.replace(`${pathname}?${params.toString()}`, { scroll: false });\n };\n\n return (\n <div className=\"w-full flex flex-col gap-10\">\n {showHeading &&\n (hero ? (\n <div className=\"space-y-4\">\n <h1 className=\"text-h1 tracking-[-1.12px] text-ods-text-primary flex items-center gap-3\">\n {hero.icon}\n {hero.title ?? section.hero.title}\n </h1>\n <p className=\"font-['DM_Sans'] font-medium text-[18px] leading-[28px] text-ods-text-secondary max-w-3xl\">\n {hero.description}\n </p>\n </div>\n ) : (\n <div className=\"flex items-center justify-between w-full\">\n <h2 className=\"font-['Azeret_Mono'] font-semibold text-[32px] md:text-[40px] lg:text-[48px] leading-[40px] md:leading-[48px] lg:leading-[56px] text-ods-text-primary tracking-[-0.64px] md:tracking-[-0.8px] lg:tracking-[-0.96px]\">\n {section.hero.title}\n <span className=\"text-ods-accent\">:</span>\n </h2>\n </div>\n ))}\n\n {preControls}\n\n {(search || filter) && (\n <div className=\"space-y-4\">\n {search && (\n <SearchInput\n showDropdown={false}\n placeholder={search.placeholder}\n value={searchValue}\n onChange={setSearchValue}\n onSubmit={handleSearchSubmit}\n />\n )}\n {filter && (\n <StatusFilterComponent\n selectedStatus={currentFilterValue}\n onStatusChange={handleFilterChange}\n statusOptions={[...filter.options]}\n />\n )}\n </div>\n )}\n\n {children}\n </div>\n );\n}\n","'use client';\n\n/**\n * DevSectionPage — full-page wrapper for a dev-center section\n * (`/roadmap`, `/bug-fixes-and-enhancements`, `/releases`).\n *\n * Mounts the lib's canonical `PageLayout` directly (no in-app wrapper)\n * so the back-button affordance stays in lockstep with whatever the\n * design system ships — any future lib change to BackButton / TitleBlock\n * propagates automatically.\n *\n * Composition: `PageShell` → `PageLayout` (back-to-home wired) →\n * `DevSectionView` (icon hero + search + filter pills) → list body.\n *\n * Adding a new section is one entry in `OPENFRAME_DEV_SECTIONS` plus a\n * single-line page file mounting this factory with the new key.\n */\n\nimport type { ReactNode } from 'react';\nimport { useRouter } from '../../../embed-shims/next-navigation';\nimport { PageShell, PageLayout } from '../../ui';\nimport { DevSectionView } from './dev-section-view';\nimport {\n OPENFRAME_DEV_SECTIONS,\n type OpenframeDevSectionKey,\n} from '../../../utils/dev-sections/openframe-dev-sections';\n\nexport interface DevSectionPageProps {\n sectionKey: OpenframeDevSectionKey;\n /** The page-specific list body (e.g. `<RoadmapList />`). */\n children: ReactNode;\n /** Optional slot rendered BETWEEN the hero and search/filter — see\n * `DevSectionView.preControls`. Used by surfaces that want an entry\n * action (e.g. Help Center's \"Open a new ticket\" form) above the\n * controls instead of below them. */\n preControls?: ReactNode;\n /** Back-button config — same shape as `LegalDocumentPage` /\n * `ReleaseDetailPage`. Pass `false` to hide entirely. Default\n * `{ label: 'Back to home', href: '/' }` — embedders whose \"home\" isn't `/`\n * should override `href`, or pass `false` if the embed has no home page. */\n backButton?: { label?: string; href?: string } | false;\n /** Override the hero title. Defaults to the (OpenFrame-specific) copy in\n * `OPENFRAME_DEV_SECTIONS[sectionKey].hero.title`. Set this to brand the\n * section for a non-OpenFrame embed. */\n title?: string;\n /** Override the hero subtitle/description. Defaults to\n * `OPENFRAME_DEV_SECTIONS[sectionKey].hero.description`. */\n subtitle?: string;\n /** Render the standalone `<PageShell>` (own `<main>` + bg + max-width). Default\n * `true` — the contract for marketing/hub surfaces with no app shell. Pass\n * `false` when the host layout already provides the page container (e.g.\n * openframe-frontend's `AppLayout` `<main>`): then only the\n * `page-shell-content` padding box is rendered, avoiding a nested `<main>`. */\n shell?: boolean;\n}\n\nexport function DevSectionPage({\n sectionKey,\n children,\n preControls,\n backButton,\n title,\n subtitle,\n shell = true,\n}: DevSectionPageProps) {\n const router = useRouter();\n const section = OPENFRAME_DEV_SECTIONS[sectionKey];\n\n // Back-button config — mirrors LegalDocumentPage / ReleaseDetailPage.\n // Default: { label: 'Back to home', href: '/' }. Pass `false` to hide.\n // After `backButton &&` narrowing, inner type is `{ label?, href? } |\n // undefined`; don't re-compare to `false` (TS2367).\n const backCfg =\n backButton === false\n ? undefined\n : {\n label: (backButton ? backButton.label : undefined) ?? 'Back to home',\n onClick: () => router.push((backButton ? backButton.href : undefined) ?? '/'),\n };\n\n const inner = (\n // Unified header: title/description route through the canonical (frozen)\n // `PageLayout` `TitleBlock` (text-h2) — same as FAQ / Legal / detail pages —\n // so every help-center surface shares one header. `DevSectionView` then\n // renders ONLY its search + filter controls (`showHeading={false}`), no\n // duplicate title. (The hero icon is intentionally dropped: TitleBlock is\n // frozen and renders title-only.)\n <PageLayout\n title={title ?? section.hero.title}\n subtitle={subtitle ?? section.hero.description}\n titleSize=\"h1\"\n titleWrap\n backButton={backCfg}\n >\n <DevSectionView sectionKey={sectionKey} showHeading={false} preControls={preControls}>\n {children}\n </DevSectionView>\n </PageLayout>\n );\n\n // `shell` true → standalone `<PageShell>` (own <main> + bg + max-width).\n // false → padding-only box (no nested <main>) for hosts whose layout already\n // provides the container; both consume the host's `--page-shell-*` vars.\n return shell ? <PageShell>{inner}</PageShell> : <div className=\"page-shell-content\">{inner}</div>;\n}\n","'use client';\n\n/**\n * Shared row chrome for any `DevSectionPage` list (delivery, tickets,\n * future sections). One source of truth for the layout that every\n * dev-section card row uses:\n * left column → title (h3) / subtitle (h5 uppercase) / description\n * (h4 line-clamp-3), each in a fixed min-height block\n * so rows align across the grid\n * right column → caller-supplied stacked badges\n *\n * Surface stays small on purpose — `rightBadges` is a `ReactNode` so\n * the caller decides how many badges (delivery: 2, tickets: 1-2,\n * future: anything). No behavior baked in: the caller wraps the row\n * in a `<div>` (static, like delivery) or `<button>` (clickable, like\n * tickets) and renders the row content via this component.\n *\n * Pair with `DevCardRowSkeletonList` for the loading state — the\n * skeleton mirrors the same min-heights so the in-flight UI doesn't\n * shift the layout when real data lands.\n *\n * NOTE: the ticket conversation row is NOT here — it renders the shared\n * `<ChatMessageRow>` (`components/chat/chat-message-row.tsx`), the SAME\n * component the OpenMSP Slack-community feed uses, so the two surfaces stay\n * pixel-identical by construction.\n */\n\nimport type { ReactNode } from 'react';\n\nexport interface DevCardRowContentProps {\n title: string;\n /** Single-line uppercase metadata (e.g. \"UPDATED today, #4271, Code review\"). */\n subtitle: string;\n /** 3-line description block. Empty string renders the fallback. */\n description: string;\n /** Fallback copy when `description` is empty. Defaults to a generic\n * string; ticket / delivery surfaces override. */\n emptyDescription?: string;\n /** Right column — caller renders its own stacked badges. */\n rightBadges: ReactNode;\n}\n\nexport function DevCardRowContent({\n title,\n subtitle,\n description,\n emptyDescription = 'No description provided',\n rightBadges,\n}: DevCardRowContentProps) {\n return (\n <div className=\"flex flex-col md:flex-row items-start justify-between gap-[12px] md:gap-[16px] w-full\">\n <div className=\"flex-1 min-w-0 w-full md:w-auto flex flex-col gap-[12px] md:gap-[16px]\">\n <div className=\"min-h-[24px] flex items-center\">\n <h3 className=\"text-h3 text-ods-text-primary tracking-[-0.36px] flex-1 line-clamp-2 md:truncate break-words\">\n {title}\n </h3>\n </div>\n <div className=\"min-h-[20px] flex items-center\">\n <p className=\"text-h5 text-ods-text-secondary uppercase tracking-[-0.28px] truncate\">\n {subtitle}\n </p>\n </div>\n <div className=\"min-h-[72px] flex items-center\">\n <p className=\"text-h4 text-ods-text-secondary line-clamp-3 break-words\">\n {description || emptyDescription}\n </p>\n </div>\n </div>\n <div className=\"flex-shrink-0 self-start flex flex-col gap-2\">\n {rightBadges}\n </div>\n </div>\n );\n}\n\n/**\n * Skeleton rendering for a single row — the bars mirror the same\n * min-heights as `DevCardRowContent` so the loading→loaded swap\n * doesn't reflow.\n */\nexport function DevCardRowSkeleton() {\n return (\n <div className=\"border-b border-ods-border last:border-b-0 p-[12px] md:p-[16px]\">\n <div className=\"flex flex-col md:flex-row items-start justify-between gap-[12px] md:gap-[16px] w-full\">\n <div className=\"flex-1 min-w-0 w-full md:w-auto flex flex-col gap-[12px] md:gap-[16px]\">\n <div className=\"min-h-[24px] flex items-center\">\n <div className=\"h-[20px] bg-ods-border rounded animate-pulse w-full\" />\n </div>\n <div className=\"min-h-[20px] flex items-center\">\n <div className=\"h-[20px] bg-ods-border rounded animate-pulse w-1/2\" />\n </div>\n <div className=\"min-h-[72px] flex items-center\">\n <div className=\"flex-1 space-y-1\">\n <div className=\"h-[20px] bg-ods-border rounded animate-pulse w-full\" />\n <div className=\"h-[20px] bg-ods-border rounded animate-pulse w-full\" />\n <div className=\"h-[20px] bg-ods-border rounded animate-pulse w-2/3\" />\n </div>\n </div>\n </div>\n <div className=\"flex-shrink-0 self-start flex flex-col gap-2\">\n <div className=\"h-[32px] w-[100px] bg-ods-border rounded animate-pulse\" />\n <div className=\"h-[32px] w-[120px] bg-ods-border rounded animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * The standard \"5 skeleton rows inside a bordered card\" loading state\n * used by every list shell. Both delivery (`delivery-table.tsx`) and\n * tickets (`tickets-list.tsx`) mount this directly.\n */\nexport function DevCardRowSkeletonList({ rows = 5 }: { rows?: number }) {\n return (\n <div className=\"bg-ods-card border border-ods-border rounded-[6px] overflow-hidden w-full\">\n {Array.from({ length: rows }, (_, i) => (\n <DevCardRowSkeleton key={i} />\n ))}\n </div>\n );\n}\n","'use client'\n\n/**\n * `<DeliveryRow />` — canonical single-row presentation for a ClickUp\n * delivery item.\n *\n * Single source of truth: both the `/bug-fixes-and-enhancements` page\n * (via `DeliveryTable`) AND the linked-delivery card on a HubSpot ticket\n * (via `TicketLinkedDeliveryCard`) compose this primitive. Visual parity\n * across those two surfaces is the design goal — the user reads the\n * card on their ticket and recognises it as a row from the public\n * delivery list.\n *\n * Behaviors:\n * - `href` set → outer element is an `<a>`, the whole row becomes\n * clickable (used by the linked-card surface to deep-link into\n * `/bug-fixes-and-enhancements?focus=<id>`).\n * - `id` set → outer element gets that DOM id so the consuming page\n * can `scrollIntoView` to it when the URL carries `?focus=<id>`.\n * - `highlighted` true → brief accent border + background pulse\n * (`animate-flash-focus` keyframe defined in `tailwind.config.ts`).\n * - `caption` set → small uppercase label rendered above the title\n * (\"LINKED DELIVERY\" on the ticket-side variant). Omitted on the\n * standard list rendering.\n */\n\nimport * as React from 'react'\nimport Link from '../../../embed-shims/next-link'\nimport { StatusBadge } from '../../ui/status-badge'\nimport { getStatusColorScheme } from '../../../utils'\nimport {\n type DeliveryItem,\n TASK_TYPE_LABELS,\n TASK_TYPE_TEXT_COLORS,\n} from '../../../types/delivery'\nimport { cn } from '../../../utils/cn'\n\n/** Same heuristic as DeliveryTable's local helper. Inlined so the row\n * primitive owns its complete rendering contract. */\nfunction getRelativeTime(timestamp: number): string {\n const now = Date.now()\n const diff = now - timestamp\n const days = Math.floor(diff / (1000 * 60 * 60 * 24))\n const weeks = Math.floor(days / 7)\n const months = Math.floor(days / 30)\n if (months > 0) return months === 1 ? 'last month' : `${months} months ago`\n if (weeks > 0) return weeks === 1 ? 'last week' : `${weeks} weeks ago`\n if (days > 0) return days === 1 ? 'yesterday' : `${days} days ago`\n return 'today'\n}\n\nexport interface DeliveryRowProps {\n item: DeliveryItem\n /** When set, the row becomes a clickable anchor. The ticket-side\n * linked-card composes this from `buildDevSectionUrl('delivery', id)`\n * which carries `?search=<id>` — the delivery list filters to that\n * exact task on landing (canonical deep-link mechanism, same one\n * the chat-inline delivery card uses). */\n href?: string\n /** Small uppercase caption rendered above the title. Used by the\n * linked-delivery card variant (\"LINKED DELIVERY\"). */\n caption?: string\n /** DOM `id` applied to the row's outer element. `DeliveryTable`\n * always sets `delivery-<external_id>` so chat-card deep-links\n * (`?search=<id>#delivery-<id>`) and the ticket linked-card path\n * both have a target for `useScrollToHash` to scroll to. Always\n * paired with `scroll-mt-24` on the outer element so the row lands\n * BELOW the sticky chrome after the scroll. */\n id?: string\n className?: string\n}\n\nexport function DeliveryRow({\n item,\n href,\n caption,\n id,\n className,\n}: DeliveryRowProps) {\n const taskType = item.taskType as keyof typeof TASK_TYPE_LABELS\n const typeBadgeLabel = TASK_TYPE_LABELS[taskType] || 'TASK'\n const typeBadgeTextColor = TASK_TYPE_TEXT_COLORS[taskType] || ''\n const statusBadgeScheme = getStatusColorScheme(item.status)\n const relativeTime = getRelativeTime(item.dateUpdated)\n const subtitle = `ACTIVE ${relativeTime}${item.listNames.length > 0 ? `, ${item.listNames.join(', ')}` : ''}, ${item.id}`\n\n const inner = (\n <div className=\"flex flex-col md:flex-row items-start justify-between gap-[12px] md:gap-[16px] w-full\">\n {/* Left: caption (optional) + title + subtitle + description */}\n <div className=\"flex-1 min-w-0 w-full md:w-auto flex flex-col gap-[12px] md:gap-[16px]\">\n {caption && (\n <p className=\"text-xs font-medium uppercase tracking-wider text-ods-text-secondary\">\n {caption}\n </p>\n )}\n <div className=\"min-h-[24px] md:min-h-[24px] flex items-center\">\n <h3 className=\"text-h3 text-ods-text-primary tracking-[-0.36px] flex-1 line-clamp-2 md:truncate break-words\">\n {item.title}\n </h3>\n </div>\n <div className=\"min-h-[20px] flex items-center\">\n <p className=\"text-h5 text-ods-text-secondary uppercase tracking-[-0.28px] truncate\">\n {subtitle}\n </p>\n </div>\n <div className=\"min-h-[72px] flex items-center\">\n <p className=\"text-h4 text-ods-text-secondary line-clamp-3 break-words\">\n {item.description || 'No description provided'}\n </p>\n </div>\n </div>\n\n {/* Right: status + task-type badges */}\n <div className=\"flex-shrink-0 self-start flex flex-col gap-2\">\n <StatusBadge\n text={item.status.toUpperCase()}\n colorScheme={statusBadgeScheme}\n variant=\"card\"\n className=\"border border-ods-border\"\n />\n <StatusBadge\n text={typeBadgeLabel}\n variant=\"card\"\n className={`border border-ods-border ${typeBadgeTextColor}`}\n />\n </div>\n </div>\n )\n\n const baseClass = cn(\n 'block p-[12px] md:p-[16px] no-underline text-inherit transition-colors duration-150',\n // `scroll-mt-24` is paid for whether `id` is set or not (it's a\n // single Tailwind utility, no runtime cost). Keeping it\n // unconditional means a future caller adding `id` doesn't also\n // have to remember to ask for the offset.\n 'scroll-mt-24',\n href && 'hover:bg-ods-bg-hover cursor-pointer',\n className,\n )\n\n if (href) {\n // `Link` is the env-aware embed-shim — delegates to `next/link` on\n // a Next.js host (soft RSC nav, back-button restores the previous\n // page's React state intact), falls back to a plain `<a>` on\n // non-Next embedders. A raw `<a href>` was hard-navigating +\n // losing TanStack-Query state on back, leaving /tickets stuck on\n // its skeleton.\n return (\n <Link href={href} id={id} className={baseClass} prefetch={false}>\n {inner}\n </Link>\n )\n }\n\n return <div id={id} className={baseClass}>{inner}</div>\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/ui/button/button-styles.ts","../src/components/ui/button/button.tsx","../src/components/ui/button/split-button.tsx","../src/components/ui/button/index.ts","../src/components/ui/field-wrapper.tsx","../src/components/ui/input.tsx","../src/components/ui/checkbox.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/ui/portal-container.tsx","../src/components/ui/skeleton.tsx"],"sourcesContent":["// Shared style atoms for `Button` and `SplitButton`. Extracted to keep a single\n// source of truth for surface colors, outline borders, and split-divider colors.\n\n// Each variant pairs `disabled:` (real `<button disabled>`) with `aria-disabled:`\n// (used for `<Link aria-disabled>` since anchors don't support `:disabled`).\nexport const buttonSurfaceClasses = {\n accent:\n \"bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover active:bg-ods-accent-active disabled:bg-ods-disabled aria-disabled:bg-ods-disabled\",\n outline:\n \"bg-ods-card text-ods-text-primary hover:bg-ods-bg-hover active:bg-ods-bg-active disabled:bg-ods-card disabled:text-ods-text-disabled aria-disabled:bg-ods-card aria-disabled:text-ods-text-disabled\",\n transparent:\n \"bg-transparent text-ods-text-primary hover:bg-ods-bg-hover active:bg-ods-bg-active disabled:bg-transparent disabled:text-ods-text-disabled aria-disabled:bg-transparent aria-disabled:text-ods-text-disabled\",\n destructive:\n \"bg-ods-error text-ods-text-on-accent hover:bg-ods-error-hover active:bg-ods-error-active disabled:bg-ods-disabled aria-disabled:bg-ods-disabled\",\n} as const\n\nexport const outlineBorderClasses =\n \"border border-ods-border hover:border-ods-border-hover active:border-ods-border-active disabled:border-ods-border aria-disabled:border-ods-border\"\n\n// Color of the vertical seam between the main and icon halves (split layouts).\nexport const splitDividerColorClasses = {\n accent: \"border-ods-accent-active\",\n outline: \"border-ods-border\",\n transparent: \"border-ods-border\",\n destructive: \"border-ods-error-active\",\n} as const\n\nexport type ButtonSurfaceVariant = keyof typeof buttonSurfaceClasses\n","\"use client\"\n\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport Link from \"../../../embed-shims/next-link\"\nimport React from \"react\"\n\nimport { cn } from \"../../../utils/cn\"\nimport { buttonSurfaceClasses, outlineBorderClasses, splitDividerColorClasses } from \"./button-styles\"\n\n// Default layout: centered single content area, padding/gap on the button itself.\nconst buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-[var(--spacing-system-xsf)]\",\n \"rounded-md whitespace-nowrap\",\n \"transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus\",\n \"disabled:pointer-events-none\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:h-5 [&_svg]:w-5\",\n ],\n {\n variants: {\n variant: {\n accent: buttonSurfaceClasses.accent,\n outline: cn(buttonSurfaceClasses.outline, outlineBorderClasses),\n transparent: buttonSurfaceClasses.transparent,\n destructive: buttonSurfaceClasses.destructive,\n },\n size: {\n default: \"py-[var(--spacing-system-sf)] px-[var(--spacing-system-m)] text-h3 md:h-12 h-10\",\n small: \"p-[var(--spacing-system-xs)] text-h5 h-6 md:h-8\",\n \"small-legacy\": \"py-[var(--spacing-system-xs)] px-[var(--spacing-system-m)] h-10 text-[14px] font-bold\", // Temporary alias for \"small\" — deprecated; grep size=\"small-legacy\" (lib + hub) and migrate the remaining consumers before removal\n // 24px pill for slim strips (announcement/promo bars, inline banner\n // actions — Primer banner / Polaris banner / Vercel-bar convention).\n // The label matches the strip's MESSAGE type ramp exactly (DM Sans\n // regular, 13px -> md:14px, snug leading — the announcement bar's\n // subtitle styling): in-strip CTAs must never read louder than the\n // message beside them, so this deliberately uses neither the\n // mono-uppercase control style of \"small\" nor a heavier weight.\n // Pinned h-6 across breakpoints (24px = the WCAG 2.5.8 target-size\n // floor) with horizontal-dominant padding and a 14px glyph.\n compact: \"py-0 px-[var(--spacing-system-sf)] font-body font-normal text-[13px] md:text-sm leading-snug h-6 [&_svg]:h-3.5 [&_svg]:w-3.5\",\n icon: \"p-[var(--spacing-system-sf)] h-11 w-11 md:h-12 md:w-12 [&_svg]:h-4 [&_svg]:w-4 md:[&_svg]:h-6 md:[&_svg]:w-6\",\n // Quiet 32px icon target with a 16px glyph, fixed across breakpoints\n // (Carbon ghost sm / Primer medium / shadcn icon-sm all pin 32px;\n // ≥ the 24px WCAG 2.5.8 target floor). For icon actions that read as\n // metadata rather than CTAs — author-page social rows, share rows.\n // Pair with variant=\"transparent\" for the ghost treatment.\n \"icon-sm\": \"p-[var(--spacing-system-xxs)] h-8 w-8 [&_svg]:h-4 [&_svg]:w-4\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n noPaddingX: {\n true: \"px-0\",\n false: \"\",\n },\n },\n compoundVariants: [\n { size: \"small\", class: \"[&_svg]:h-4 [&_svg]:w-4\" },\n ],\n defaultVariants: {\n variant: \"accent\",\n size: \"default\",\n fullWidth: false,\n noPaddingX: false,\n },\n }\n)\n\n// Split layout (used when `splitIcon` is provided): outer button has no padding;\n// inner slots own padding/gap so the divider can span full button height.\nconst splitShellVariants = cva(\n [\n \"group relative inline-flex items-stretch overflow-hidden rounded-md whitespace-nowrap\",\n \"transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus\",\n \"disabled:pointer-events-none\",\n ],\n {\n variants: {\n variant: {\n accent: buttonSurfaceClasses.accent,\n outline: cn(buttonSurfaceClasses.outline, outlineBorderClasses),\n transparent: buttonSurfaceClasses.transparent,\n destructive: buttonSurfaceClasses.destructive,\n },\n size: {\n default: \"h-12 text-h3\",\n small: \"h-6 md:h-8 text-h5\",\n },\n fullWidth: { true: \"w-full\", false: \"\" },\n },\n defaultVariants: { variant: \"accent\", size: \"default\", fullWidth: false },\n }\n)\n\nconst splitSlotVariants = cva(\n [\"inline-flex items-center justify-center\", \"[&_svg]:shrink-0 [&_svg]:h-5 [&_svg]:w-5\"],\n {\n variants: {\n slot: {\n main: \"gap-[var(--spacing-system-xsf)]\",\n icon: \"border-l\",\n },\n size: { default: \"\", small: \"[&_svg]:h-4 [&_svg]:w-4\" },\n variant: { accent: \"\", outline: \"\", transparent: \"\", destructive: \"\" },\n },\n compoundVariants: [\n { slot: \"main\", size: \"default\", class: \"px-[var(--spacing-system-m)] py-[var(--spacing-system-sf)]\" },\n { slot: \"main\", size: \"small\", class: \"px-[var(--spacing-system-xs)]\" },\n { slot: \"icon\", size: \"default\", class: \"w-10\" },\n { slot: \"icon\", size: \"small\", class: \"w-6 md:w-8\" },\n { slot: \"icon\", variant: \"accent\", class: cn(\n splitDividerColorClasses.accent,\n \"group-disabled:border-ods-disabled group-aria-disabled:border-ods-disabled\",\n ) },\n { slot: \"icon\", variant: \"outline\", class: splitDividerColorClasses.outline },\n { slot: \"icon\", variant: \"transparent\", class: splitDividerColorClasses.transparent },\n { slot: \"icon\", variant: \"destructive\", class: cn(\n splitDividerColorClasses.destructive,\n \"group-disabled:border-ods-disabled group-aria-disabled:border-ods-disabled\",\n ) },\n ],\n defaultVariants: { slot: \"main\", size: \"default\", variant: \"accent\" },\n }\n)\n\n/** @deprecated Use `size=\"small\"` instead. Temporary alias kept for backward compatibility; will be removed in the future. */\ntype DeprecatedButtonSize = \"small-legacy\"\n\ntype ButtonSize = Exclude<VariantProps<typeof buttonVariants>[\"size\"], \"small-legacy\" | null | undefined> | DeprecatedButtonSize\n\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n Omit<VariantProps<typeof buttonVariants>, \"size\"> {\n asChild?: boolean\n href?: string\n openInNewTab?: boolean\n prefetch?: boolean\n /**\n * Pre-resolved anchor bundle (from `useNavLink({ href, targetPlatform })`).\n * When set, renders the Button as `<Link>` with `href` / `target` / `rel`\n * / `onClick` spread from this object. Lets callers thread the unified\n * nav decision directly without `<Button asChild><a {...linkProps}/>`\n * gymnastics. Wins over the separate `href` / `openInNewTab` props.\n */\n linkProps?: {\n href: string\n target?: '_blank'\n rel?: 'noopener noreferrer'\n onClick?: React.MouseEventHandler<HTMLAnchorElement>\n } | null\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n /**\n * Renders a vertical divider and trailing icon area inside the button.\n * The whole button stays a single click target — the icon is decorative\n * (`aria-hidden`). For two independent click targets, use `<SplitButton>`.\n * Only honored when `size` is `\"default\"` or `\"small\"`.\n */\n splitIcon?: React.ReactNode\n loading?: boolean\n size?: ButtonSize\n}\n\nconst Spinner = () => (\n <svg className=\"animate-spin\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n)\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n fullWidth,\n noPaddingX,\n asChild,\n href,\n openInNewTab,\n prefetch,\n linkProps,\n leftIcon,\n rightIcon,\n splitIcon,\n loading,\n children,\n disabled,\n onClick,\n ...props\n },\n ref,\n) {\n const isDisabled = disabled || loading\n\n // splitIcon is only supported for default/small sizes. With other sizes\n // (icon, small-legacy) we silently fall back to the normal layout.\n const useSplitLayout = !!splitIcon && (size === \"default\" || size === \"small\" || size === undefined)\n\n if (useSplitLayout) {\n const safeSize = (size ?? \"default\") as \"default\" | \"small\"\n const safeVariant = (variant ?? \"accent\") as \"accent\" | \"outline\" | \"transparent\" | \"destructive\"\n const shellClasses = cn(\n splitShellVariants({ variant: safeVariant, size: safeSize, fullWidth }),\n className,\n )\n const mainSlotClass = splitSlotVariants({ slot: \"main\", size: safeSize, variant: safeVariant })\n const iconSlotClass = splitSlotVariants({ slot: \"icon\", size: safeSize, variant: safeVariant })\n\n const splitContent = (\n <>\n <span className={cn(\"contents\", loading && \"invisible\")}>\n <span className={mainSlotClass}>\n {leftIcon && <span className=\"inline-flex items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex items-center\">{rightIcon}</span>}\n </span>\n <span aria-hidden=\"true\" className={iconSlotClass}>\n {splitIcon}\n </span>\n </span>\n {loading && (\n <span className=\"absolute inset-0 inline-flex items-center justify-center text-ods-text-primary\">\n <Spinner />\n </span>\n )}\n </>\n )\n\n // `linkProps` (the pre-resolved bundle from `useNavLink({ href, targetPlatform })`)\n // wins over the legacy `href` + `openInNewTab` props so callers can thread\n // the unified nav decision directly. Either path produces the same `<Link>`.\n const splitAnchor = linkProps ?? (href ? {\n href,\n target: openInNewTab ? '_blank' as const : undefined,\n rel: openInNewTab ? 'noopener noreferrer' as const : undefined,\n onClick: onClick as unknown as React.MouseEventHandler<HTMLAnchorElement> | undefined,\n } : null)\n if (splitAnchor) {\n return (\n <Link\n href={splitAnchor.href}\n prefetch={prefetch}\n target={splitAnchor.target}\n rel={splitAnchor.rel}\n // The Link branches don't spread {...props} (button attrs don't\n // belong on an anchor), but the accessible name MUST survive —\n // icon-only link buttons have no text content.\n aria-label={props['aria-label']}\n aria-disabled={isDisabled || undefined}\n tabIndex={isDisabled ? -1 : undefined}\n className={cn(shellClasses, isDisabled && \"pointer-events-none\")}\n onClick={splitAnchor.onClick}\n >\n {splitContent}\n </Link>\n )\n }\n\n return (\n <button\n ref={ref}\n className={shellClasses}\n disabled={isDisabled}\n onClick={onClick}\n {...props}\n >\n {splitContent}\n </button>\n )\n }\n\n const classes = cn(buttonVariants({ variant, size, fullWidth, noPaddingX }), className)\n\n // asChild: consumer fully controls the rendered element; we just stamp our classes.\n if (asChild) {\n return (\n <Slot ref={ref} className={classes} {...props}>\n {children}\n </Slot>\n )\n }\n\n // Real content stays in layout (preserving width) but goes invisible while loading.\n // The spinner is absolutely positioned so it never shifts the button's size.\n const content = (\n <>\n <span className={cn(\"contents\", loading && \"invisible\")}>\n {leftIcon && <span className=\"inline-flex items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex items-center\">{rightIcon}</span>}\n </span>\n {loading && (\n <span className=\"absolute inset-0 inline-flex items-center justify-center text-ods-text-primary\">\n <Spinner />\n </span>\n )}\n </>\n )\n\n // Same `linkProps`-wins-over-href resolution as the splitIcon branch.\n const anchor = linkProps ?? (href ? {\n href,\n target: openInNewTab ? '_blank' as const : undefined,\n rel: openInNewTab ? 'noopener noreferrer' as const : undefined,\n onClick: onClick as unknown as React.MouseEventHandler<HTMLAnchorElement> | undefined,\n } : null)\n if (anchor) {\n return (\n <Link\n href={anchor.href}\n prefetch={prefetch}\n target={anchor.target}\n rel={anchor.rel}\n // See the splitAnchor branch — keep the accessible name on the\n // anchor render (icon-only link buttons have no text content).\n aria-label={props['aria-label']}\n aria-disabled={isDisabled || undefined}\n tabIndex={isDisabled ? -1 : undefined}\n className={cn(classes, isDisabled && \"pointer-events-none\")}\n onClick={anchor.onClick}\n >\n {content}\n </Link>\n )\n }\n\n return (\n <button\n ref={ref}\n className={classes}\n disabled={isDisabled}\n onClick={onClick}\n {...props}\n >\n {content}\n </button>\n )\n})\n\nexport { Button, buttonVariants, type ButtonProps }\n","\"use client\"\n\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport Link from \"../../../embed-shims/next-link\"\nimport React from \"react\"\n\nimport { cn } from \"../../../utils/cn\"\nimport { buttonSurfaceClasses, splitDividerColorClasses } from \"./button-styles\"\n\n// Two independent interactive halves: each a `<button>` or `<a>`. The seam is\n// a 1px border on the left edge of the icon half, colored per variant. For a\n// single-target variant (decorative trailing icon), use `<Button splitIcon>`.\n\nconst splitHalfBase = [\n \"relative inline-flex items-center justify-center gap-[var(--spacing-system-xsf)]\",\n \"whitespace-nowrap transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus focus-visible:z-10\",\n \"disabled:pointer-events-none\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n]\n\nconst splitHalfVariants = cva(splitHalfBase, {\n variants: {\n variant: {\n accent: buttonSurfaceClasses.accent,\n outline: buttonSurfaceClasses.outline, // Outline border lives in compoundVariants so we can omit the seam edge.\n transparent: buttonSurfaceClasses.transparent,\n destructive: buttonSurfaceClasses.destructive,\n },\n size: {\n default: \"h-10 md:h-12 px-[var(--spacing-system-m)] py-[var(--spacing-system-sf)] text-h3 [&_svg]:h-4 [&_svg]:w-4 md:[&_svg]:h-6 md:[&_svg]:w-6\",\n small: \"h-6 md:h-8 px-[var(--spacing-system-xs)] text-h5 [&_svg]:h-3 [&_svg]:w-3 md:[&_svg]:h-4 md:[&_svg]:w-4\",\n },\n side: { main: \"\", icon: \"\" },\n soloOnMobile: { true: \"\", false: \"\" },\n },\n compoundVariants: [\n // Rounded corners + per-variant seam. The icon-side's left border is the divider.\n { variant: \"accent\", side: \"main\", class: \"rounded-l-md\" },\n { variant: \"accent\", side: \"icon\", class: cn(\n \"rounded-r-md border-l\",\n splitDividerColorClasses.accent,\n \"disabled:border-ods-disabled aria-disabled:border-ods-disabled\",\n ) },\n { variant: \"destructive\", side: \"main\", class: \"rounded-l-md\" },\n { variant: \"destructive\", side: \"icon\", class: cn(\n \"rounded-r-md border-l\",\n splitDividerColorClasses.destructive,\n \"disabled:border-ods-disabled aria-disabled:border-ods-disabled\",\n ) },\n { variant: \"outline\", side: \"main\", class: \"rounded-l-md border-y border-l border-ods-border\" },\n { variant: \"outline\", side: \"icon\", class: \"rounded-r-md border border-ods-border\" },\n { variant: \"transparent\", side: \"main\", class: \"rounded-md\" },\n { variant: \"transparent\", side: \"icon\", class: cn(\"rounded-md\", splitDividerColorClasses.transparent) },\n\n // Icon half: per Figma, narrower than main height (default: 40×48; small: 32×32).\n { side: \"icon\", size: \"default\", class: \"w-10 px-0\" },\n { side: \"icon\", size: \"small\", class: \"w-6 md:w-8 px-0\" },\n\n { side: \"icon\", soloOnMobile: true, class: \"max-md:hidden\" },\n { side: \"main\", soloOnMobile: true, class: \"max-md:rounded-r-md\" },\n { variant: \"outline\", side: \"main\", soloOnMobile: true, class: \"max-md:border-r\" },\n ],\n defaultVariants: { variant: \"accent\", size: \"default\", side: \"main\", soloOnMobile: false },\n})\n\ntype SplitButtonVariant = NonNullable<VariantProps<typeof splitHalfVariants>[\"variant\"]>\ntype SplitButtonSize = NonNullable<VariantProps<typeof splitHalfVariants>[\"size\"]>\n\ninterface SplitButtonIconAction {\n icon: React.ReactNode\n /** The icon half is interactive but has no visible text — needs an accessible name. */\n \"aria-label\": string\n onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>\n href?: string\n /**\n * Opens `href` with `target=\"_blank\"`. Also marks the half as a new-tab\n * affordance, which hides it below `md` (set it for `onClick` handlers that\n * open a new tab/window themselves).\n */\n openInNewTab?: boolean\n prefetch?: boolean\n disabled?: boolean\n}\n\ninterface SplitButtonProps {\n variant?: SplitButtonVariant\n size?: SplitButtonSize\n fullWidth?: boolean\n className?: string\n\n children: React.ReactNode\n onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>\n href?: string\n openInNewTab?: boolean\n prefetch?: boolean\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n /** Disables both halves. Equivalent to `mainDisabled && iconAction.disabled`. */\n disabled?: boolean\n /** Disables only the main half. Combine with `iconAction.disabled` for finer control. */\n mainDisabled?: boolean\n type?: \"button\" | \"submit\" | \"reset\"\n \"aria-label\"?: string\n groupAriaLabel?: string\n\n iconAction: SplitButtonIconAction\n}\n\ninterface HalfOptions {\n variant: SplitButtonVariant\n size: SplitButtonSize\n side: \"main\" | \"icon\"\n soloOnMobile?: boolean\n href?: string\n openInNewTab?: boolean\n prefetch?: boolean\n onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>\n disabled?: boolean\n /** Stretch this half to fill the group's free space (the icon half stays fixed-width). */\n grow?: boolean\n type?: \"button\" | \"submit\" | \"reset\"\n ariaLabel?: string\n children: React.ReactNode\n}\n\nfunction Half({ variant, size, side, soloOnMobile, href, openInNewTab, prefetch, onClick, disabled, grow, type = \"button\", ariaLabel, children }: HalfOptions) {\n const classes = cn(splitHalfVariants({ variant, size, side, soloOnMobile }), grow && \"flex-1\")\n\n if (href) {\n return (\n <Link\n href={href}\n prefetch={prefetch}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noopener noreferrer\" : undefined}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : undefined}\n aria-label={ariaLabel}\n className={cn(classes, disabled && \"pointer-events-none\")}\n onClick={onClick as unknown as React.MouseEventHandler<HTMLAnchorElement> | undefined}\n >\n {children}\n </Link>\n )\n }\n\n return (\n <button\n type={type}\n className={classes}\n disabled={disabled}\n aria-label={ariaLabel}\n onClick={onClick as React.MouseEventHandler<HTMLButtonElement>}\n >\n {children}\n </button>\n )\n}\n\nconst SplitButton = React.forwardRef<HTMLDivElement, SplitButtonProps>(function SplitButton(\n {\n variant = \"accent\",\n size = \"default\",\n fullWidth = false,\n className,\n children,\n onClick,\n href,\n openInNewTab,\n prefetch,\n leftIcon,\n rightIcon,\n disabled,\n mainDisabled,\n type,\n iconAction,\n \"aria-label\": ariaLabel,\n groupAriaLabel,\n },\n ref,\n) {\n const soloOnMobile = !!iconAction.openInNewTab\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={groupAriaLabel}\n className={cn(\"inline-flex items-stretch\", fullWidth && \"w-full\", className)}\n >\n <Half\n variant={variant}\n size={size}\n side=\"main\"\n soloOnMobile={soloOnMobile}\n href={href}\n openInNewTab={openInNewTab}\n prefetch={prefetch}\n onClick={onClick}\n disabled={disabled || mainDisabled}\n grow={fullWidth}\n type={type}\n ariaLabel={ariaLabel}\n >\n {leftIcon && <span className=\"inline-flex items-center\">{leftIcon}</span>}\n <span>{children}</span>\n {rightIcon && <span className=\"inline-flex items-center\">{rightIcon}</span>}\n </Half>\n <Half\n variant={variant}\n size={size}\n side=\"icon\"\n soloOnMobile={soloOnMobile}\n href={iconAction.href}\n openInNewTab={iconAction.openInNewTab}\n prefetch={iconAction.prefetch}\n onClick={iconAction.onClick}\n disabled={disabled || iconAction.disabled}\n ariaLabel={iconAction[\"aria-label\"]}\n >\n <span className=\"inline-flex items-center\">{iconAction.icon}</span>\n </Half>\n </div>\n )\n})\n\nexport { SplitButton, type SplitButtonProps, type SplitButtonIconAction }\n","export * from './button'\nexport * from './split-button'\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../utils/cn\"\n\nexport interface FieldWrapperProps {\n /** Label text displayed above the field */\n label?: string\n /** Status message displayed below the field. Wraps up to two lines, then ellipsizes. */\n error?: string\n /** Color variant for the message: \"error\" (red), \"warning\" (yellow), \"success\" (green) or \"muted\" (grey) */\n errorVariant?: \"error\" | \"warning\" | \"success\" | \"muted\"\n /** Additional className for the outer wrapper */\n className?: string\n children: React.ReactNode\n}\n\nconst errorVariantClasses = {\n error: \"text-ods-error\",\n warning: \"text-[var(--ods-attention-yellow-warning)]\",\n success: \"text-ods-success\",\n muted: \"text-ods-text-secondary\",\n} as const\n\nconst FieldWrapper = React.forwardRef<HTMLDivElement, FieldWrapperProps>(\n ({ label, error, errorVariant = \"error\", className, children }, ref) => {\n const hasChrome = label != null || error != null\n\n return (\n <div ref={ref} className={cn(hasChrome ? \"flex w-full flex-col\" : \"contents\", className)}>\n {label && (\n <label className=\"text-h4 text-ods-text-primary mb-1\">\n {label}\n </label>\n )}\n {children}\n {error && (\n <p\n className={cn(\"mt-1 text-h6 break-words line-clamp-2\", errorVariantClasses[errorVariant])}\n title={error}\n >\n {error}\n </p>\n )}\n </div>\n )\n }\n)\nFieldWrapper.displayName = \"FieldWrapper\"\n\nexport { FieldWrapper }\n","\"use client\"\n\nimport * as React from \"react\";\n\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { FieldWrapper } from \"./field-wrapper\";\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n /** When true, renders error border & ring */\n invalid?: boolean;\n /** Element displayed at the start (left) of the input */\n startAdornment?: React.ReactNode;\n /** Element displayed at the end (right) of the input */\n endAdornment?: React.ReactNode;\n /** Label text displayed above the input */\n label?: string;\n /** Status message displayed below the input */\n error?: string;\n /** Color variant for the message: \"error\" (red), \"warning\" (yellow), \"success\" (green) or \"muted\" (grey).\n Only \"error\" and \"warning\" mark the field invalid (colored border). */\n errorVariant?: \"error\" | \"warning\" | \"success\" | \"muted\";\n /** When true, shows a loading spinner as end adornment */\n loading?: boolean;\n}\n\nconst invalidBorderClasses = {\n error: \"border-ods-error hover:border-ods-error has-[:focus]:border-ods-error\",\n warning: \"!border-[var(--ods-attention-yellow-warning)] hover:!border-[var(--ods-attention-yellow-warning)] has-[:focus]:!border-[var(--ods-attention-yellow-warning)]\",\n} as const;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, invalid = false, startAdornment, endAdornment, label, error, errorVariant = \"error\", loading = false, ...props }, ref) => {\n // success/muted are informational — they never paint the invalid border\n const variantIsInvalid = errorVariant === \"error\" || errorVariant === \"warning\"\n const isInvalid = invalid || (!!error && variantIsInvalid)\n\n // Range inputs get a clean slider rendering — no label wrapper, borders, or adornments\n if (type === 'range') {\n const rangeInput = (\n <input\n type=\"range\"\n className={cn(\n \"w-full cursor-pointer appearance-none rounded-full bg-white/30 h-1\",\n // Webkit (Chrome/Safari) thumb\n \"[&::-webkit-slider-thumb]:appearance-none\",\n \"[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3\",\n \"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white\",\n \"[&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:shadow-sm\",\n // Firefox thumb\n \"[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3\",\n \"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white\",\n \"[&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:cursor-pointer\",\n // Firefox track\n \"[&::-moz-range-track]:bg-transparent\",\n // Disabled\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n return label ? (\n <FieldWrapper label={label} error={error} errorVariant={errorVariant}>\n {rangeInput}\n </FieldWrapper>\n ) : rangeInput\n }\n\n const content = (\n <label\n data-invalid={isInvalid || undefined}\n className={cn(\n // Layout & spacing\n \"flex w-full items-center gap-2 rounded-[6px] border px-3 h-11 md:h-12 cursor-text\",\n // Focus-within states\n \"has-[:focus-visible]:outline-none\",\n \"group\",\n // Animations & touch UX\n \"transition-colors duration-200\",\n // Theme palette\n \"bg-ods-card border-ods-border has-[:focus]:border-ods-accent\",\n // Hover & active (not disabled)\n !props.disabled && \"hover:bg-ods-bg-hover hover:border-ods-border-hover active:bg-ods-bg-active active:border-ods-border-active\",\n // Disabled\n props.disabled && \"!cursor-not-allowed bg-ods-bg\",\n // Invalid\n isInvalid && invalidBorderClasses[variantIsInvalid ? (errorVariant as \"error\" | \"warning\") : \"error\"],\n className\n )}\n >\n {startAdornment && (\n <span className=\"text-h6 flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent group-data-[invalid]:text-ods-error [&_svg]:size-4 md:[&_svg]:size-6\">\n {startAdornment}\n </span>\n )}\n <input\n type={type}\n className={cn(\n // Layout\n \"flex-1 min-w-0 bg-transparent border-none outline-none\",\n // Typography\n \"text-h4\",\n // Colors\n \"text-ods-text-primary placeholder:text-ods-text-secondary\",\n // File input adjustments\n \"file:border-0 file:bg-transparent\",\n // Disabled\n \"disabled:cursor-not-allowed disabled:text-ods-text-disabled disabled:placeholder:text-ods-border\",\n // Touch\n \"touch-manipulation\",\n // Autofill override\n \"[&:-webkit-autofill]:[-webkit-box-shadow:0_0_0_9999px_transparent_inset] [&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-text-primary)] [&:-webkit-autofill]:[caret-color:var(--color-text-primary)] [&:-webkit-autofill]:[transition:background-color_9999s_ease-in-out_0s]\"\n )}\n ref={ref}\n {...props}\n />\n {loading && (\n <Loader2 className=\"animate-spin flex-shrink-0 text-ods-text-secondary size-4 md:size-6\" />\n )}\n {!loading && endAdornment && (\n <span className=\"text-h6 flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent group-data-[invalid]:text-ods-error [&_svg]:size-4 md:[&_svg]:size-6\">\n {endAdornment}\n </span>\n )}\n </label>\n )\n\n return (\n <FieldWrapper label={label} error={error} errorVariant={errorVariant}>\n {content}\n </FieldWrapper>\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input };\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\"\n\nimport { cn } from \"../../utils/cn\"\nimport { CheckboxCheckmarkIcon } from \"../icons-v2-generated/signs-and-symbols/checkbox-checkmark-icon\"\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <CheckboxPrimitive.Root\n ref={ref}\n className={cn(\n \"peer h-4 w-4 shrink-0 rounded-sm border border-ods-border bg-ods-card focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-ods-accent data-[state=checked]:border-ods-accent\",\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n className={cn(\"flex items-center justify-center text-ods-text-on-accent\")}\n >\n <CheckboxCheckmarkIcon size={10} />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n))\nCheckbox.displayName = CheckboxPrimitive.Root.displayName\n\nexport { Checkbox }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { Check, ChevronRight, Circle } from \"lucide-react\"\n\nimport { cn } from \"../../utils/cn\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst DropdownMenu = DropdownMenuPrimitive.Root\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n \"flex cursor-pointer gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-ods-bg-hover focus:bg-ods-bg-hover data-[state=open]:bg-ods-bg-hover [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && \"pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownMenuSubTrigger.displayName =\n DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border border-ods-border bg-ods-card p-1 text-ods-text-primary shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n))\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => {\n // Portal into the active container (e.g. a drawer) so the menu inherits its\n // stacking context; falls back to `document.body` when none is provided.\n const container = usePortalContainer()\n return (\n <DropdownMenuPrimitive.Portal container={container ?? undefined}>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border border-ods-border bg-ods-card p-1 text-ods-text-primary shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n})\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-base outline-none transition-colors text-ods-text-primary hover:bg-ods-bg-hover hover:text-ods-text-primary focus:bg-ods-bg-hover focus:text-ods-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && \"pl-8\",\n className\n )}\n {...props}\n />\n))\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors text-ods-text-primary hover:bg-ods-bg-hover hover:text-ods-text-primary focus:bg-ods-bg-hover focus:text-ods-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownMenuCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors text-ods-text-primary hover:bg-ods-bg-hover hover:text-ods-text-primary focus:bg-ods-bg-hover focus:text-ods-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-ods-accent\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n))\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n \"px-2 py-1.5 text-sm font-semibold text-ods-text-secondary\",\n inset && \"pl-8\",\n className\n )}\n {...props}\n />\n))\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-ods-border\", className)}\n {...props}\n />\n))\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\"ml-auto text-xs tracking-widest text-ods-text-secondary opacity-60\", className)}\n {...props}\n />\n )\n}\nDropdownMenuShortcut.displayName = \"DropdownMenuShortcut\"\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n}\n","'use client'\n\nimport * as React from 'react'\n\n/**\n * The DOM node that Radix overlays (dropdown menus, tooltips) should portal\n * into, instead of the default `document.body`.\n *\n * Portaling to `document.body` lifts content out of every local stacking\n * context, which forces overlays opened *inside* a high-z surface (e.g. the\n * chat drawer) to escalate their own z-index to compete at the document\n * root. Pointing the portal at a node *inside* that surface instead\n * lets the content inherit the surface's stacking context — small, local\n * z-indices then \"just work\" and no escalation is needed. Radix positions\n * content with `strategy: \"fixed\"`, so it still escapes ancestor\n * `overflow: hidden` clipping regardless of where it is portaled.\n *\n * Default `null` → Radix falls back to `document.body` (unchanged behaviour\n * everywhere a provider isn't present).\n */\nexport const PortalContainerContext = React.createContext<HTMLElement | null>(\n null,\n)\n\n/** Read the active portal container (or `null` to use `document.body`). */\nexport function usePortalContainer(): HTMLElement | null {\n return React.useContext(PortalContainerContext)\n}\n","\"use client\"\n\nimport * as React from 'react'\nimport { cn } from \"../../utils/cn\"\n\ninterface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n className?: string\n}\n\nconst Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"animate-pulse rounded-md bg-ods-border\",\n className\n )}\n {...props}\n />\n )\n }\n)\nSkeleton.displayName = 'Skeleton'\n\ninterface SkeletonTextProps extends React.HTMLAttributes<HTMLDivElement> {\n lines?: number\n className?: string\n}\n\nconst SkeletonText = React.forwardRef<HTMLDivElement, SkeletonTextProps>(\n ({ lines = 1, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"space-y-2\", className)} {...props}>\n {Array.from({ length: lines }).map((_, i) => (\n <Skeleton \n key={i} \n className={cn(\n \"h-4\",\n i === lines - 1 && lines > 1 && \"w-3/4\" // Last line shorter for multi-line\n )} \n />\n ))}\n </div>\n )\n }\n)\nSkeletonText.displayName = 'SkeletonText'\n\ninterface SkeletonCardProps extends React.HTMLAttributes<HTMLDivElement> {\n showImage?: boolean\n className?: string\n}\n\nconst SkeletonCard = React.forwardRef<HTMLDivElement, SkeletonCardProps>(\n ({ showImage = false, className, ...props }, ref) => {\n return (\n <div \n ref={ref}\n className={cn(\n \"rounded-lg border border-ods-border overflow-hidden\",\n className\n )}\n {...props}\n >\n {showImage && (\n <Skeleton className=\"h-48 w-full\" />\n )}\n <div className=\"p-6\">\n <Skeleton className=\"h-6 w-3/4 mb-4\" />\n <SkeletonText lines={3} />\n </div>\n </div>\n )\n }\n)\nSkeletonCard.displayName = 'SkeletonCard'\n\ninterface SkeletonGridProps extends React.HTMLAttributes<HTMLDivElement> {\n columns?: number\n items?: number\n showImages?: boolean\n className?: string\n}\n\nconst SkeletonGrid = React.forwardRef<HTMLDivElement, SkeletonGridProps>(\n ({ columns = 3, items = 6, showImages = false, className, ...props }, ref) => {\n return (\n <div \n ref={ref}\n className={cn(\n `grid grid-cols-1 gap-6`,\n columns === 2 && \"md:grid-cols-2\",\n columns === 3 && \"md:grid-cols-3\",\n columns === 4 && \"md:grid-cols-4\",\n className\n )}\n {...props}\n >\n {Array.from({ length: items }).map((_, i) => (\n <SkeletonCard key={i} showImage={showImages} />\n ))}\n </div>\n )\n }\n)\nSkeletonGrid.displayName = 'SkeletonGrid'\n\ninterface SkeletonButtonProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: 'sm' | 'default' | 'lg'\n className?: string\n}\n\nconst SkeletonButton = React.forwardRef<HTMLDivElement, SkeletonButtonProps>(\n ({ size = 'default', className, ...props }, ref) => {\n const sizeClasses = {\n sm: 'h-8 w-20',\n default: 'h-10 w-32',\n lg: 'h-12 w-40'\n }\n \n return (\n <Skeleton \n ref={ref}\n className={cn(\n \"rounded-lg\",\n sizeClasses[size],\n className\n )}\n {...props}\n />\n )\n }\n)\nSkeletonButton.displayName = 'SkeletonButton'\n\ninterface SkeletonHeadingProps extends React.HTMLAttributes<HTMLDivElement> {\n level?: 1 | 2 | 3 | 4 | 5 | 6\n className?: string\n}\n\nconst SkeletonHeading = React.forwardRef<HTMLDivElement, SkeletonHeadingProps>(\n ({ level = 1, className, ...props }, ref) => {\n const heightClasses = {\n 1: 'h-12',\n 2: 'h-10',\n 3: 'h-8',\n 4: 'h-7',\n 5: 'h-6',\n 6: 'h-5'\n }\n \n return (\n <Skeleton \n ref={ref}\n className={cn(\n heightClasses[level],\n \"w-3/4\",\n className\n )}\n {...props}\n />\n )\n }\n)\nSkeletonHeading.displayName = 'SkeletonHeading'\n\ninterface SkeletonListProps extends React.HTMLAttributes<HTMLDivElement> {\n items?: number\n className?: string\n}\n\nconst SkeletonList = React.forwardRef<HTMLDivElement, SkeletonListProps>(\n ({ items = 5, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"space-y-3\", className)} {...props}>\n {Array.from({ length: items }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-3\">\n <Skeleton className=\"h-10 w-10 rounded-full flex-shrink-0\" />\n <div className=\"flex-1\">\n <Skeleton className=\"h-4 w-1/3 mb-1\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n </div>\n ))}\n </div>\n )\n }\n)\nSkeletonList.displayName = 'SkeletonList'\n\ninterface SkeletonNavigationProps extends React.HTMLAttributes<HTMLDivElement> {\n items?: number\n className?: string\n}\n\nconst SkeletonNavigation = React.forwardRef<HTMLDivElement, SkeletonNavigationProps>(\n ({ items = 6, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex items-center gap-6\", className)} {...props}>\n {Array.from({ length: items }).map((_, i) => (\n <Skeleton key={i} className=\"h-5 w-20\" />\n ))}\n </div>\n )\n }\n)\nSkeletonNavigation.displayName = 'SkeletonNavigation'\n\nexport { \n Skeleton,\n SkeletonText,\n SkeletonCard,\n SkeletonGrid,\n SkeletonButton,\n SkeletonHeading,\n SkeletonList,\n SkeletonNavigation\n}"],"mappings":"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","names":["React","jsx","jsxs","Button","cva","React","jsx","jsxs","SplitButton","init_button","React","jsx","jsxs","React","jsx","React","React","jsx","jsxs","React","jsx","jsxs"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/shared/doc-search/format-relative-path.ts","../src/components/shared/doc-search/doc-search-result-row.tsx","../src/components/shared/doc-search/doc-search-bar.tsx","../src/components/shared/doc-search/map-doc-search-results.ts","../src/components/shared/doc-search/resolve-search-result-action.ts","../src/components/shared/doc-search/use-doc-search.ts"],"sourcesContent":["/**\n * Format a full document path as a breadcrumb trail.\n * Shows parent folders only (excludes the last segment / filename).\n *\n * @example\n * formatRelativePath('openframe-oss-tenant/architecture/api-controllers.md')\n * // → 'Openframe oss tenant / Architecture'\n */\nexport function formatRelativePath(fullPath: string): string {\n if (!fullPath) return ''\n const segments = fullPath.replace(/\\.md$/, '').split('/')\n // Show only parent path (exclude the filename itself since the title already shows it)\n const parentSegments = segments.length > 1 ? segments.slice(0, -1) : segments\n return parentSegments\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).replace(/-/g, ' '))\n .join(' / ')\n}\n","'use client'\n\n/**\n * Single row in the `<SearchInput>` dropdown — the standard layout\n * used by every doc-search-backed surface (company-hub data-room\n * search bar, onboarding-guide catalog search, …). Single source of\n * truth for the row appearance so search dropdowns are visually\n * identical everywhere.\n *\n * Resolves the source icon via the same `resolveSourceIcon()`\n * registry the inline chat-card refs use, so a row pointing at e.g.\n * an onboarding-guide surfaces the SAME `<GraduationCap>` glyph the\n * chat card surfaces — no cross-surface drift.\n */\n\nimport { resolveSourceIcon } from '../../chat/utils/source-row-cta'\nimport { formatRelativePath } from './format-relative-path'\n\n/**\n * Minimal result shape this row renders. Compatible with any\n * doc-search hook whose result type exposes `{ title?, path?,\n * metadata? }`. The two hub consumers (onboarding-guide catalog,\n * data-room sidebar) both satisfy this shape via their\n * `useDocSearch` hook result.\n */\nexport interface DocSearchResultRowEntry {\n title?: string\n path?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface DocSearchResultRowProps {\n result: DocSearchResultRowEntry\n isHighlighted: boolean\n}\n\nexport function DocSearchResultRow({\n result,\n isHighlighted,\n}: DocSearchResultRowProps) {\n const docType = (result.metadata?.documentType as string) || undefined\n const sourceRepo = (result.metadata?.sourceRepo as string) || undefined\n const { Icon: SourceIcon, label: iconLabel } = resolveSourceIcon({\n sourceRepo,\n documentType: docType,\n })\n const isGroup = result.metadata?.isGroup as boolean | undefined\n\n return (\n <div className=\"flex items-center gap-3 w-full min-w-0\">\n <span\n className=\"flex-shrink-0 text-ods-text-secondary\"\n title={iconLabel}\n >\n <SourceIcon className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div\n className={`text-sm font-medium leading-5 truncate ${\n isHighlighted ? 'text-ods-accent' : 'text-ods-text-primary'\n }`}\n >\n {result.title || result.path}\n </div>\n {!isGroup && result.path?.includes('/') && (\n <div className=\"text-xs leading-4 text-ods-text-secondary truncate mt-0.5\">\n {formatRelativePath(result.path)}\n </div>\n )}\n </div>\n </div>\n )\n}\n","'use client'\n\n/**\n * `<DocSearchBar>` — the canonical RAG-search dropdown surface.\n *\n * Mounted by every doc-search consumer (data-room sidebar, onboarding-\n * guide catalog, and any future surface that needs typeahead against\n * `/api/docs/search`). Wraps `<SearchInput>` with the lib's standard\n * `<DocSearchResultRow>` so the dropdown looks identical everywhere.\n *\n * ## Why a presentation component, not a \"search bar that owns its\n * own hook\"\n *\n * The data-fetching hook (`useDocSearch`) lives hub-side because it\n * depends on hub-only context (`useDocNavigation`, the rag-table-\n * config registry, the hub's `decideNewTab` helper). Moving the hook\n * would cascade ~5 more file migrations into the lib.\n *\n * Instead, the hook stays hub-side and callers pass its result into\n * this component as plain props. Both consumers shrink to ~5 lines.\n */\n\nimport type { ReactNode } from 'react'\nimport { SearchInput, type SearchResult } from '../../ui/search-input'\nimport { DocSearchResultRow } from './doc-search-result-row'\n\nexport interface DocSearchBarProps {\n placeholder: string\n query: string\n onQueryChange: (value: string) => void\n /** Hook-fetched results. Reuses the lib's `<SearchInput>` `SearchResult`\n * shape directly so callers don't translate. */\n results: SearchResult[]\n isLoading: boolean\n /** Result selection handler. Mirrors `<SearchInput>` — the second\n * `modifiers` argument is preserved so cmd-click / shift-click on\n * a result row still forces new-tab behavior. Hub `useDocSearch`\n * reads these to short-circuit to `window.open()`. */\n onResultSelect: (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => void\n /** Lets the caller's hook force the dropdown open after a recent\n * internal action (e.g. result navigation). `undefined` falls back\n * to `<SearchInput>`'s built-in focus/hover heuristics. */\n showDropdown?: boolean\n /** Defaults to 2 — matches the existing data-room and onboarding-\n * guide consumers. Override only if a surface needs different\n * typeahead semantics. */\n minQueryLength?: number\n /** Defaults to 0 — both existing consumers debounce inside the\n * hook, not the input. */\n debounceMs?: number\n className?: string\n /** Optional row-renderer override. Defaults to the lib's standard\n * `<DocSearchResultRow>` (source icon + title + path breadcrumb).\n * Override only when a surface needs custom row chrome. */\n renderResult?: (result: SearchResult, isHighlighted: boolean) => ReactNode\n}\n\nexport function DocSearchBar({\n placeholder,\n query,\n onQueryChange,\n results,\n isLoading,\n onResultSelect,\n showDropdown,\n minQueryLength = 2,\n debounceMs = 0,\n className = 'w-full',\n renderResult,\n}: DocSearchBarProps) {\n return (\n <SearchInput\n placeholder={placeholder}\n value={query}\n onChange={onQueryChange}\n results={results}\n isLoading={isLoading}\n onResultSelect={onResultSelect}\n showDropdown={showDropdown || undefined}\n debounceMs={debounceMs}\n minQueryLength={minQueryLength}\n className={className}\n renderResult={\n renderResult ??\n ((result, isHighlighted) => (\n <DocSearchResultRow result={result} isHighlighted={isHighlighted} />\n ))\n }\n />\n )\n}\n","/**\n * Map RAG `/api/docs/search` wire results into the `<DocSearchBar>`\n * dropdown's row shape, collapsing entity-table rows into grouped\n * results so the dropdown lists ONE \"Cap Table (12 records)\" row\n * instead of 12 individual rows.\n *\n * Pure transform — no telemetry, no navigation, no React deps. Lifted\n * from the hub's `hooks/use-docs.ts:mapDocSearchResults` (the hub's\n * `traceCompose` call was hub-only telemetry and is intentionally\n * dropped — callers that want logging can wrap this helper).\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { DocSearchResult } from './types'\n\n/** Source repos that should be collapsed into grouped results in the search bar.\n * Only financial tables (all rows link to the same admin page).\n * Content tables (blog, webinar, podcast, etc.) stay individual since each has a unique URL. */\nconst SEARCH_GROUP_REPOS = new Set([\n 'financial-cap-table',\n 'financial-kpis',\n 'financial-pnl',\n 'financial-balance-sheet',\n 'financial-cash-flow',\n])\n\nconst ENTITY_LABELS: Record<string, string> = {\n 'financial-cap-table': 'Cap Table',\n 'financial-kpis': 'Financial KPIs',\n 'financial-pnl': 'Profit & Loss',\n 'financial-balance-sheet': 'Balance Sheets',\n 'financial-cash-flow': 'Cash Flow',\n 'blog-posts': 'Blog Posts',\n 'product-releases': 'Product Releases',\n 'case-studies': 'Case Studies',\n webinars: 'Webinars',\n events: 'Events',\n podcasts: 'Podcasts',\n}\n\nexport function mapDocSearchResults(docs: DocSearchResult[]): SearchResult[] {\n const entityGroups = new Map<string, DocSearchResult[]>()\n // Track insertion order — groups appear where the FIRST row of that\n // repo appeared in the response.\n const order: Array<\n { type: 'entity'; repo: string } | { type: 'doc'; doc: DocSearchResult }\n > = []\n const seenRepos = new Set<string>()\n\n for (const doc of docs) {\n if (doc.sourceRepo && SEARCH_GROUP_REPOS.has(doc.sourceRepo)) {\n const group = entityGroups.get(doc.sourceRepo) || []\n group.push(doc)\n entityGroups.set(doc.sourceRepo, group)\n if (!seenRepos.has(doc.sourceRepo)) {\n seenRepos.add(doc.sourceRepo)\n order.push({ type: 'entity', repo: doc.sourceRepo })\n }\n } else {\n order.push({ type: 'doc', doc })\n }\n }\n\n const results: SearchResult[] = []\n for (const entry of order) {\n if (entry.type === 'entity') {\n const rows = entityGroups.get(entry.repo)!\n const label = ENTITY_LABELS[entry.repo] || entry.repo\n results.push({\n id: `group-${entry.repo}`,\n title: `${label} (${rows.length} ${rows.length === 1 ? 'record' : 'records'})`,\n path: rows[0].path,\n type: 'file',\n metadata: {\n documentType: rows[0].documentType,\n externalUrl: rows[0].externalUrl,\n sourceRepo: entry.repo,\n id: rows[0].entityId,\n isGroup: true,\n items: rows.map((r) => ({\n name: r.name,\n externalUrl: r.externalUrl,\n id: r.entityId,\n sourceRepo: r.sourceRepo,\n documentType: r.documentType,\n })),\n },\n })\n } else {\n const doc = entry.doc\n const isNonMarkdown = doc.documentType && doc.documentType !== 'markdown'\n results.push({\n id: doc.path,\n title: doc.name,\n description: isNonMarkdown ? doc.name : doc.snippet,\n path: doc.path,\n type: doc.type,\n metadata: {\n matchType: doc.matchType,\n ...(doc.documentType ? { documentType: doc.documentType } : {}),\n ...(doc.externalUrl ? { externalUrl: doc.externalUrl } : {}),\n ...(doc.targetPlatform != null\n ? { targetPlatform: doc.targetPlatform }\n : {}),\n ...(doc.sourceRepo ? { sourceRepo: doc.sourceRepo } : {}),\n ...(doc.entityId ? { id: doc.entityId } : {}),\n },\n })\n }\n }\n\n return results\n}\n","/**\n * Resolve what should happen when the user picks a search result.\n * Returns one of five typed actions so the caller is a single switch.\n *\n * Resolution order:\n * 1. `externalUrl` present → use `decideNewTab` to choose same-tab vs\n * new-tab against the row's `targetPlatform`.\n * 2. Row has `id` + `sourceRepo` + `documentType` → synth an Ask-AI\n * action (entity drill-in via primary key, no URL).\n * 3. Row has only `path` → legacy navigation fallback.\n * 4. Nothing actionable → noop.\n *\n * Lifted from the hub's `hooks/use-docs.ts:resolveSearchResultAction`.\n * Pure — no React, no telemetry.\n */\n\nimport type { SearchResult } from '../../ui/search-input'\nimport type { ChatRef } from '../../chat/chat-ref.types'\nimport { decideNewTab } from '../../chat/utils/decide-new-tab'\n\nexport type SearchResultAction =\n | { kind: 'navigate-same-tab'; href: string }\n | { kind: 'navigate-new-tab'; href: string }\n | { kind: 'ask-ai'; detail: { source: string; ref: ChatRef } }\n | { kind: 'route'; path: string }\n | { kind: 'noop' }\n\nexport function resolveSearchResultAction(\n result: SearchResult,\n source: string,\n runtimeMode?: 'host' | 'embed',\n): SearchResultAction {\n const meta = result.metadata ?? {}\n const externalUrl = meta.externalUrl as string | undefined\n if (externalUrl) {\n // Same pure helper `useNavLink` and `useUnifiedNav` call — single\n // decision rule across cards, chips, and autocomplete rows. Thread\n // the caller's `source` as `currentSource` so the platform-vs-\n // platform comparison matches the hub's pre-migration behavior.\n const targetPlatform = meta.targetPlatform as string | null | undefined\n const isNewTab = decideNewTab({\n href: externalUrl,\n targetPlatform,\n surface: 'useUnifiedNav',\n runtimeMode,\n currentSource: source,\n })\n return isNewTab\n ? { kind: 'navigate-new-tab', href: externalUrl }\n : { kind: 'navigate-same-tab', href: externalUrl }\n }\n const rowId = meta.id as string | undefined\n const sourceRepo = meta.sourceRepo as string | undefined\n const documentType = meta.documentType as string | undefined\n if (rowId && sourceRepo && documentType) {\n return {\n kind: 'ask-ai',\n detail: {\n source,\n ref: { type: documentType, id: rowId, title: result.title, url: null },\n },\n }\n }\n if (result.path) {\n return { kind: 'route', path: result.path }\n }\n return { kind: 'noop' }\n}\n","'use client'\n\n/**\n * `useDocSearch` — debounced RAG-search hook against `/api/docs/search`.\n *\n * Pure fetch + navigation glue. Embedders can mount this directly\n * (any host with a reverse-proxy that exposes `/api/docs/search` will\n * work). Hub callers wire it into the lib `<DocSearchBar>` for the\n * canonical typeahead dropdown.\n *\n * ## What moved from hub to lib\n *\n * Lifted from `multi-platform-hub/hooks/use-docs.ts:useDocSearch`. Two\n * hub-only concerns are now optional injection points instead of\n * direct imports:\n *\n * - `useDocNavigation()` (hub's in-page doc-tree swap) → optional\n * `onInPageSwap?: (path: string) => boolean` config callback. When\n * present and returns true, the hook treats a same-origin result\n * click as \"handled in-page\"; when absent or returns false, the\n * hook falls back to `onNavigate(path)` (`router.push` on hub,\n * `window.location.assign` on bare embedders).\n * - `traceCompose` (hub-only telemetry) → dropped. The lib has no\n * equivalent runtime-context yet; bring it back when there is one.\n *\n * Everything else (debounce, `useChatRuntime` for embed-mode short-\n * circuit, embed-shim router, the action-resolver + result-mapper) is\n * now lib-resident.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useRouter } from '../../../embed-shims'\nimport { useDebounce } from '../../../hooks/ui/use-debounce'\nimport { useChatRuntime } from '../../../contexts/chat-runtime-context'\nimport { contentFetch } from '../../../utils/embed-content-fetch'\nimport type { SearchResult } from '../../ui/search-input'\nimport {\n resolveExternalNavigation,\n stripSameOriginToPath,\n NEW_TAB_FEATURES,\n} from '../../chat/utils/chat-nav-resolution'\nimport type { DocSearchResult } from './types'\nimport { mapDocSearchResults } from './map-doc-search-results'\nimport { resolveSearchResultAction } from './resolve-search-result-action'\n\nexport interface UseDocSearchConfig {\n /** Discriminator passed to `/api/docs/search?source=` (e.g.\n * `'openframe'`). Embedders set it to whatever discriminator their\n * reverse-proxy expects. */\n source: string\n /** Base route prefix this search lives under (e.g. `'/onboarding-guides'`).\n * When a result's href starts with `${baseRoute}/`, the hook\n * attempts the optional in-page swap path before falling through\n * to a full nav. */\n baseRoute: string\n /** Imperative navigation fallback. Called when no override\n * (in-page swap, new-tab) applies. Hub callers pass\n * `(path) => router.push(path)`; embedders pass an equivalent. */\n onNavigate: (path: string) => void\n /** Optional `RagTableConfig.id` list to narrow the search to specific\n * tables (e.g. `['onboarding-guides']`). Forwarded to\n * `/api/docs/search?tableIds=…` which intersects with the source's\n * standing set. */\n tableIds?: string[]\n /** Optional in-page swap callback. When the result's href is under\n * `baseRoute` AND this callback returns true, the hook treats the\n * click as handled in-page (no router push). Hub's\n * `<DocumentationSection>` wires this to\n * `useDocNavigation().navigate(path)`. */\n onInPageSwap?: (path: string) => boolean\n /** Optional endpoint override. Defaults to `'/api/docs/search'`\n * (the hub's reverse-proxy route). Embedders with a different\n * path can override. */\n searchEndpoint?: string\n}\n\nexport function useDocSearch(config: UseDocSearchConfig) {\n const {\n source,\n baseRoute,\n onNavigate,\n tableIds,\n onInPageSwap,\n searchEndpoint,\n } = config\n const tableIdsKey = tableIds && tableIds.length > 0 ? tableIds.join(',') : ''\n\n const router = useRouter()\n // Optional chat-runtime read — when present and mode='embed' the\n // search-result row click short-circuits to a new-tab open against\n // the absolutized URL. Null/host preserves today's behavior.\n // Also used as the proxy-prefix fallback for `searchEndpoint`, matching\n // how tickets resolves `findTicketUrl`.\n const runtime = useChatRuntime()\n const resolvedSearchEndpoint =\n searchEndpoint ?? runtime?.endpoints.docsSearchUrl ?? '/api/docs/search'\n\n const [query, setQuery] = useState('')\n const [results, setResults] = useState<SearchResult[]>([])\n const [isFetching, setIsFetching] = useState(false)\n const debouncedQuery = useDebounce(query, 300)\n\n useEffect(() => {\n if (!debouncedQuery || debouncedQuery.trim().length < 2) {\n setResults([])\n setIsFetching(false)\n return\n }\n\n let cancelled = false\n\n async function fetchResults() {\n setIsFetching(true)\n try {\n const params = new URLSearchParams({\n q: debouncedQuery,\n source,\n limit: '10',\n })\n if (tableIdsKey) params.set('tableIds', tableIdsKey)\n\n const response = await contentFetch(`${resolvedSearchEndpoint}?${params.toString()}`)\n if (!response.ok) {\n throw new Error(`Search request failed: ${response.status}`)\n }\n\n const json = await response.json()\n\n if (!cancelled && json.success && Array.isArray(json.data)) {\n const mapped = mapDocSearchResults(json.data as DocSearchResult[])\n setResults(mapped)\n }\n } catch (error) {\n console.error('Doc search error:', error)\n if (!cancelled) {\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setIsFetching(false)\n }\n }\n }\n\n fetchResults()\n\n return () => {\n cancelled = true\n }\n }, [debouncedQuery, source, tableIdsKey, resolvedSearchEndpoint])\n\n // Derived loading state — single source of truth for \"should the\n // dropdown show 'Loading...' instead of 'No results found'\":\n const isLoading =\n query.trim().length >= 2 && (query !== debouncedQuery || isFetching)\n\n // Track whether dropdown should stay open (external link opened in new tab).\n const [keepOpen, setKeepOpen] = useState(false)\n\n const handleResultSelect = useCallback(\n (\n result: SearchResult,\n modifiers?: {\n metaKey?: boolean\n ctrlKey?: boolean\n shiftKey?: boolean\n altKey?: boolean\n button?: number\n },\n ) => {\n const action = resolveSearchResultAction(\n result,\n source,\n runtime?.navigation.mode,\n )\n // Modifier / non-primary mouse click → force new tab regardless of\n // same-tab/new-tab decision. The dropdown row is a `<div>`, not an\n // `<a target=\"_blank\">`, so the browser doesn't background-tab\n // natively on cmd-click. Honor it explicitly here for parity with\n // the anchor-based surfaces (cards, chips, related-content). Plain\n // Enter from the keyboard passes `modifiers === undefined`.\n const wantsNewTab =\n modifiers &&\n (modifiers.metaKey ||\n modifiers.ctrlKey ||\n modifiers.shiftKey ||\n modifiers.altKey ||\n (typeof modifiers.button === 'number' && modifiers.button !== 0))\n switch (action.kind) {\n case 'navigate-same-tab': {\n // Embed-mode short-circuit — autocomplete row clicked while\n // the chat panel is hosted inside an embedding app.\n if (runtime?.navigation.mode === 'embed') {\n setKeepOpen(true)\n const targetPlatform =\n (result.metadata?.targetPlatform as string | null | undefined) ?? null\n resolveExternalNavigation({\n href: action.href,\n targetPlatform,\n runtime,\n }).open()\n return\n }\n if (wantsNewTab) {\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n }\n // Same-origin click:\n // 1. If the href is under the current doc-tree's baseRoute AND\n // an `onInPageSwap` callback is wired AND returns true →\n // consider in-page swap handled.\n // 2. Otherwise → embed-shim `router.push()` (soft RSC nav on\n // Next.js hosts, window.location.assign on bare hosts).\n setKeepOpen(false)\n const path =\n baseRoute && action.href.startsWith(`${baseRoute}/`)\n ? action.href.slice(baseRoute.length + 1)\n : null\n if (path && onInPageSwap?.(path)) return\n router.push(stripSameOriginToPath(action.href))\n return\n }\n case 'navigate-new-tab':\n // Cross-origin (e.g. clicking a flamingo.run release from\n // product-hub) — open in a new tab. Keep dropdown open so the\n // user can pick another result without re-searching.\n setKeepOpen(true)\n window.open(action.href, '_blank', NEW_TAB_FEATURES)\n return\n case 'ask-ai':\n // Row is searchable-but-not-openable (cap_table positions,\n // financial-kpi snapshots, anything backed by\n // `resolveUrl: () => null`). Dispatch a CustomEvent that\n // GlobalAskAI listens for — opens chat + drills via\n // `entityIdFilter` (primary-key only, same as inline-card Ask).\n setKeepOpen(false)\n window.dispatchEvent(\n new CustomEvent('ask-ai:open-with-ref', { detail: action.detail }),\n )\n return\n case 'route':\n // Final fallback: legacy navigation by path. Hits when a row\n // has neither URL nor pk metadata — a mapper/API regression.\n setKeepOpen(false)\n onNavigate(action.path)\n return\n case 'noop':\n return\n }\n },\n [onNavigate, source, baseRoute, router, onInPageSwap, runtime],\n )\n\n // Reset keepOpen when query changes.\n useEffect(() => {\n setKeepOpen(false)\n }, [query])\n\n return {\n query,\n setQuery,\n results,\n isLoading,\n handleResultSelect,\n keepDropdownOpen: keepOpen,\n }\n}\n"],"mappings":"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","names":["jsx"]}