@ably/ui 17.4.2 → 17.4.3

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 (339) hide show
  1. package/AGENTS.md +573 -0
  2. package/README.md +120 -68
  3. package/core/Accordion/types.js.map +1 -1
  4. package/core/Accordion/utils.js +1 -1
  5. package/core/Accordion/utils.js.map +1 -1
  6. package/core/Accordion.js +1 -1
  7. package/core/Accordion.js.map +1 -1
  8. package/core/Badge.js +1 -1
  9. package/core/Badge.js.map +1 -1
  10. package/core/Code/Code.test.js +2 -0
  11. package/core/Code/Code.test.js.map +1 -0
  12. package/core/Code.js +1 -1
  13. package/core/Code.js.map +1 -1
  14. package/core/CodeSnippet/ApiKeySelector.js +1 -1
  15. package/core/CodeSnippet/ApiKeySelector.js.map +1 -1
  16. package/core/CodeSnippet/CodeSnippet.test.js +2 -0
  17. package/core/CodeSnippet/CodeSnippet.test.js.map +1 -0
  18. package/core/CodeSnippet/CopyButton.js +1 -1
  19. package/core/CodeSnippet/CopyButton.js.map +1 -1
  20. package/core/CodeSnippet/LanguageSelector.js +1 -1
  21. package/core/CodeSnippet/LanguageSelector.js.map +1 -1
  22. package/core/CodeSnippet/PlainCodeView.js +1 -1
  23. package/core/CodeSnippet/PlainCodeView.js.map +1 -1
  24. package/core/CodeSnippet/TooltipButton.js +1 -1
  25. package/core/CodeSnippet/TooltipButton.js.map +1 -1
  26. package/core/CodeSnippet/languages.js +1 -1
  27. package/core/CodeSnippet/languages.js.map +1 -1
  28. package/core/CodeSnippet/languages.test.js +2 -0
  29. package/core/CodeSnippet/languages.test.js.map +1 -0
  30. package/core/CodeSnippet.js +1 -1
  31. package/core/CodeSnippet.js.map +1 -1
  32. package/core/ConnectStateWrapper.js.map +1 -1
  33. package/core/ContentTile.js +2 -0
  34. package/core/ContentTile.js.map +1 -0
  35. package/core/DropdownMenu.js +1 -1
  36. package/core/DropdownMenu.js.map +1 -1
  37. package/core/Expander.js +1 -1
  38. package/core/Expander.js.map +1 -1
  39. package/core/FeaturedLink.js +1 -1
  40. package/core/FeaturedLink.js.map +1 -1
  41. package/core/Flash.js +1 -1
  42. package/core/Flash.js.map +1 -1
  43. package/core/Flyout.js +1 -1
  44. package/core/Flyout.js.map +1 -1
  45. package/core/Footer/data.js +1 -1
  46. package/core/Footer/data.js.map +1 -1
  47. package/core/Footer.js +1 -1
  48. package/core/Footer.js.map +1 -1
  49. package/core/Header/HeaderLinks.js +1 -1
  50. package/core/Header/HeaderLinks.js.map +1 -1
  51. package/core/Header/types.js +2 -0
  52. package/core/Header/types.js.map +1 -0
  53. package/core/Header.js +1 -1
  54. package/core/Header.js.map +1 -1
  55. package/core/Icon/components/icon-display-cloud-servers-mono.js +2 -0
  56. package/core/Icon/components/icon-display-cloud-servers-mono.js.map +1 -0
  57. package/core/Icon/components/icon-display-data-integrity.js +2 -0
  58. package/core/Icon/components/icon-display-data-integrity.js.map +1 -0
  59. package/core/Icon/components/icon-display-database-connector.js +2 -0
  60. package/core/Icon/components/icon-display-database-connector.js.map +1 -0
  61. package/core/Icon/components/icon-display-ephemeral-messages-dark-col.js +2 -0
  62. package/core/Icon/components/icon-display-ephemeral-messages-dark-col.js.map +1 -0
  63. package/core/Icon/components/icon-display-ephemeral-messages.js +2 -0
  64. package/core/Icon/components/icon-display-ephemeral-messages.js.map +1 -0
  65. package/core/Icon/components/icon-display-live-updates.js +2 -0
  66. package/core/Icon/components/icon-display-live-updates.js.map +1 -0
  67. package/core/Icon/components/icon-display-message-annotations-dark-col.js +2 -0
  68. package/core/Icon/components/icon-display-message-annotations-dark-col.js.map +1 -0
  69. package/core/Icon/components/icon-display-message-annotations.js +2 -0
  70. package/core/Icon/components/icon-display-message-annotations.js.map +1 -0
  71. package/core/Icon/components/icon-display-multi-user-spaces.js +2 -0
  72. package/core/Icon/components/icon-display-multi-user-spaces.js.map +1 -0
  73. package/core/Icon/components/icon-display-sdks.js +2 -0
  74. package/core/Icon/components/icon-display-sdks.js.map +1 -0
  75. package/core/Icon/components/icon-display-something-else-mono.js +2 -0
  76. package/core/Icon/components/icon-display-something-else-mono.js.map +1 -0
  77. package/core/Icon/components/icon-display-something-else.js +2 -0
  78. package/core/Icon/components/icon-display-something-else.js.map +1 -0
  79. package/core/Icon/components/icon-display-ui-mono.js +2 -0
  80. package/core/Icon/components/icon-display-ui-mono.js.map +1 -0
  81. package/core/Icon/components/icon-display-ui.js +2 -0
  82. package/core/Icon/components/icon-display-ui.js.map +1 -0
  83. package/core/Icon/components/icon-gui-checklist-checked.js +1 -1
  84. package/core/Icon/components/icon-gui-checklist-checked.js.map +1 -1
  85. package/core/Icon/components/icon-gui-code-doc.js +1 -1
  86. package/core/Icon/components/icon-gui-code-doc.js.map +1 -1
  87. package/core/Icon/components/icon-gui-cursor.js +1 -1
  88. package/core/Icon/components/icon-gui-cursor.js.map +1 -1
  89. package/core/Icon/components/icon-gui-expand.js +1 -1
  90. package/core/Icon/components/icon-gui-expand.js.map +1 -1
  91. package/core/Icon/components/icon-gui-filter-flow-step-0.js +1 -1
  92. package/core/Icon/components/icon-gui-filter-flow-step-0.js.map +1 -1
  93. package/core/Icon/components/icon-gui-flower-growth.js +1 -1
  94. package/core/Icon/components/icon-gui-flower-growth.js.map +1 -1
  95. package/core/Icon/components/icon-gui-glasses.js +1 -1
  96. package/core/Icon/components/icon-gui-glasses.js.map +1 -1
  97. package/core/Icon/components/icon-gui-heartbeat-outline.js +2 -0
  98. package/core/Icon/components/icon-gui-heartbeat-outline.js.map +1 -0
  99. package/core/Icon/components/icon-gui-heartbeat-solid.js +2 -0
  100. package/core/Icon/components/icon-gui-heartbeat-solid.js.map +1 -0
  101. package/core/Icon/components/icon-gui-mouse.js +1 -1
  102. package/core/Icon/components/icon-gui-mouse.js.map +1 -1
  103. package/core/Icon/components/icon-gui-pitfall.js +1 -1
  104. package/core/Icon/components/icon-gui-pitfall.js.map +1 -1
  105. package/core/Icon/components/icon-gui-prod-ai-transport-outline.js +2 -0
  106. package/core/Icon/components/icon-gui-prod-ai-transport-outline.js.map +1 -0
  107. package/core/Icon/components/icon-gui-prod-ai-transport-solid.js +2 -0
  108. package/core/Icon/components/icon-gui-prod-ai-transport-solid.js.map +1 -0
  109. package/core/Icon/components/icon-gui-quote-marks-fill.js +1 -1
  110. package/core/Icon/components/icon-gui-quote-marks-fill.js.map +1 -1
  111. package/core/Icon/components/icon-product-ai-transport-mono.js +2 -0
  112. package/core/Icon/components/icon-product-ai-transport-mono.js.map +1 -0
  113. package/core/Icon/components/icon-product-ai-transport.js +2 -0
  114. package/core/Icon/components/icon-product-ai-transport.js.map +1 -0
  115. package/core/Icon/components/icon-product-chat-mono.js +1 -1
  116. package/core/Icon/components/icon-product-chat-mono.js.map +1 -1
  117. package/core/Icon/components/icon-product-liveobjects-mono.js +1 -1
  118. package/core/Icon/components/icon-product-liveobjects-mono.js.map +1 -1
  119. package/core/Icon/components/icon-product-livesync-mono.js +1 -1
  120. package/core/Icon/components/icon-product-livesync-mono.js.map +1 -1
  121. package/core/Icon/components/icon-product-pubsub-mono.js +1 -1
  122. package/core/Icon/components/icon-product-pubsub-mono.js.map +1 -1
  123. package/core/Icon/components/icon-product-spaces-mono.js +1 -1
  124. package/core/Icon/components/icon-product-spaces-mono.js.map +1 -1
  125. package/core/Icon/components/icon-tech-claude-mono.js +2 -0
  126. package/core/Icon/components/icon-tech-claude-mono.js.map +1 -0
  127. package/core/Icon/components/icon-tech-claude.js +2 -0
  128. package/core/Icon/components/icon-tech-claude.js.map +1 -0
  129. package/core/Icon/components/icon-tech-jetpack.js +2 -0
  130. package/core/Icon/components/icon-tech-jetpack.js.map +1 -0
  131. package/core/Icon/components/icon-tech-terraform-outline.js +2 -0
  132. package/core/Icon/components/icon-tech-terraform-outline.js.map +1 -0
  133. package/core/Icon/components/index.js +1 -1
  134. package/core/Icon/components/index.js.map +1 -1
  135. package/core/Icon/computed-icons/display-icons.js +1 -1
  136. package/core/Icon/computed-icons/display-icons.js.map +1 -1
  137. package/core/Icon/computed-icons/gui-icons.js +1 -1
  138. package/core/Icon/computed-icons/gui-icons.js.map +1 -1
  139. package/core/Icon/computed-icons/product-icons.js +1 -1
  140. package/core/Icon/computed-icons/product-icons.js.map +1 -1
  141. package/core/Icon/computed-icons/tech-icons.js +1 -1
  142. package/core/Icon/computed-icons/tech-icons.js.map +1 -1
  143. package/core/Icon.js +1 -1
  144. package/core/Icon.js.map +1 -1
  145. package/core/LinkButton.js +1 -1
  146. package/core/LinkButton.js.map +1 -1
  147. package/core/Logo.js +1 -1
  148. package/core/Logo.js.map +1 -1
  149. package/core/Meganav/MeganavBlog.js +2 -0
  150. package/core/Meganav/MeganavBlog.js.map +1 -0
  151. package/core/Meganav/MeganavCustomerStories.js +2 -0
  152. package/core/Meganav/MeganavCustomerStories.js.map +1 -0
  153. package/core/Meganav/MeganavMobile.js +1 -1
  154. package/core/Meganav/MeganavMobile.js.map +1 -1
  155. package/core/Meganav/MeganavPanel.js +1 -1
  156. package/core/Meganav/MeganavPanel.js.map +1 -1
  157. package/core/Meganav/MeganavPanelItemLinks.js +2 -0
  158. package/core/Meganav/MeganavPanelItemLinks.js.map +1 -0
  159. package/core/Meganav/MeganavTile.js +2 -0
  160. package/core/Meganav/MeganavTile.js.map +1 -0
  161. package/core/Meganav/PanelTitle.js +2 -0
  162. package/core/Meganav/PanelTitle.js.map +1 -0
  163. package/core/Meganav/data.js +1 -1
  164. package/core/Meganav/data.js.map +1 -1
  165. package/core/Meganav/images/cust-logo-doxy-dark.png +0 -0
  166. package/core/Meganav/images/cust-logo-doxy-light.png +0 -0
  167. package/core/Meganav/utils/getMenuItemsForHeader.js +2 -0
  168. package/core/Meganav/utils/getMenuItemsForHeader.js.map +1 -0
  169. package/core/Meganav.js +1 -1
  170. package/core/Meganav.js.map +1 -1
  171. package/core/Notice/component.css +9 -3
  172. package/core/Notice/component.js +1 -1
  173. package/core/Notice/component.js.map +1 -1
  174. package/core/Notice.js +1 -1
  175. package/core/Notice.js.map +1 -1
  176. package/core/Pricing/PricingCards.js +1 -1
  177. package/core/Pricing/PricingCards.js.map +1 -1
  178. package/core/Pricing/data.js +1 -1
  179. package/core/Pricing/data.js.map +1 -1
  180. package/core/Pricing/types.js.map +1 -1
  181. package/core/ProductTile/ProductDescription.js +1 -1
  182. package/core/ProductTile/ProductDescription.js.map +1 -1
  183. package/core/ProductTile/ProductIcon.js +1 -1
  184. package/core/ProductTile/ProductIcon.js.map +1 -1
  185. package/core/ProductTile/ProductLabel.js +1 -1
  186. package/core/ProductTile/ProductLabel.js.map +1 -1
  187. package/core/ProductTile/data.js +1 -1
  188. package/core/ProductTile/data.js.map +1 -1
  189. package/core/ProductTile.js +1 -1
  190. package/core/ProductTile.js.map +1 -1
  191. package/core/SegmentedControl.js +1 -1
  192. package/core/SegmentedControl.js.map +1 -1
  193. package/core/Slider/component.js +1 -1
  194. package/core/Slider/component.js.map +1 -1
  195. package/core/Slider.js +1 -1
  196. package/core/Slider.js.map +1 -1
  197. package/core/TabMenu.js +1 -1
  198. package/core/TabMenu.js.map +1 -1
  199. package/core/Table/data.js +1 -1
  200. package/core/Table/data.js.map +1 -1
  201. package/core/Toggle.js +1 -1
  202. package/core/Toggle.js.map +1 -1
  203. package/core/Tooltip.js +1 -1
  204. package/core/Tooltip.js.map +1 -1
  205. package/core/fonts/NEXT-Book-Light-Italic.eot +0 -0
  206. package/core/fonts/NEXT-Book-Light-Italic.otf +0 -0
  207. package/core/fonts/NEXT-Book-Light-Italic.woff +0 -0
  208. package/core/fonts/NEXT-Book-Light-Italic.woff2 +0 -0
  209. package/core/fonts/NEXT-Book-Light.eot +0 -0
  210. package/core/fonts/NEXT-Book-Light.otf +0 -0
  211. package/core/fonts/NEXT-Book-Light.woff +0 -0
  212. package/core/fonts/NEXT-Book-Light.woff2 +0 -0
  213. package/core/fonts/NEXT-Book-Medium-Italic.eot +0 -0
  214. package/core/fonts/NEXT-Book-Medium-Italic.otf +0 -0
  215. package/core/fonts/NEXT-Book-Medium-Italic.woff +0 -0
  216. package/core/fonts/NEXT-Book-Medium-Italic.woff2 +0 -0
  217. package/core/fonts/NEXT-Book-Medium.eot +0 -0
  218. package/core/fonts/NEXT-Book-Medium.otf +0 -0
  219. package/core/fonts/NEXT-Book-Medium.woff +0 -0
  220. package/core/fonts/NEXT-Book-Medium.woff2 +0 -0
  221. package/core/hooks/use-content-height.js +2 -0
  222. package/core/hooks/use-content-height.js.map +1 -0
  223. package/core/hooks/use-themed-scrollpoints.js +2 -0
  224. package/core/hooks/use-themed-scrollpoints.js.map +1 -0
  225. package/core/hooks/use-themed-scrollpoints.test.js +2 -0
  226. package/core/hooks/use-themed-scrollpoints.test.js.map +1 -0
  227. package/core/icons/display/icon-display-cloud-servers-mono.svg +3 -0
  228. package/core/icons/display/icon-display-data-integrity.svg +9 -0
  229. package/core/icons/display/icon-display-database-connector.svg +13 -0
  230. package/core/icons/display/icon-display-ephemeral-messages-dark-col.svg +6 -0
  231. package/core/icons/display/icon-display-ephemeral-messages.svg +6 -0
  232. package/core/icons/display/icon-display-live-updates.svg +8 -0
  233. package/core/icons/display/icon-display-message-annotations-dark-col.svg +11 -0
  234. package/core/icons/display/icon-display-message-annotations.svg +11 -0
  235. package/core/icons/display/icon-display-multi-user-spaces.svg +13 -0
  236. package/core/icons/display/icon-display-sdks.svg +11 -0
  237. package/core/icons/display/icon-display-something-else-mono.svg +4 -0
  238. package/core/icons/display/icon-display-something-else.svg +4 -0
  239. package/core/icons/display/icon-display-ui-mono.svg +22 -0
  240. package/core/icons/display/icon-display-ui.svg +22 -0
  241. package/core/icons/gui/icon-gui-checklist-checked.svg +1 -1
  242. package/core/icons/gui/icon-gui-code-doc.svg +1 -1
  243. package/core/icons/gui/icon-gui-cursor.svg +1 -1
  244. package/core/icons/gui/icon-gui-expand.svg +1 -1
  245. package/core/icons/gui/icon-gui-filter-flow-step-0.svg +3 -3
  246. package/core/icons/gui/icon-gui-flower-growth.svg +1 -1
  247. package/core/icons/gui/icon-gui-glasses.svg +1 -1
  248. package/core/icons/gui/icon-gui-heartbeat-outline.svg +4 -0
  249. package/core/icons/gui/icon-gui-heartbeat-solid.svg +4 -0
  250. package/core/icons/gui/icon-gui-mouse.svg +1 -1
  251. package/core/icons/gui/icon-gui-pitfall.svg +1 -1
  252. package/core/icons/gui/icon-gui-prod-ai-transport-outline.svg +5 -0
  253. package/core/icons/gui/icon-gui-prod-ai-transport-solid.svg +5 -0
  254. package/core/icons/gui/icon-gui-quote-marks-fill.svg +2 -2
  255. package/core/icons/product/icon-product-ai-transport-mono.svg +5 -0
  256. package/core/icons/product/icon-product-ai-transport.svg +12 -0
  257. package/core/icons/product/icon-product-chat-mono.svg +1 -1
  258. package/core/icons/product/icon-product-liveobjects-mono.svg +1 -4
  259. package/core/icons/product/icon-product-livesync-mono.svg +4 -4
  260. package/core/icons/product/icon-product-pubsub-mono.svg +1 -1
  261. package/core/icons/product/icon-product-spaces-mono.svg +1 -1
  262. package/core/icons/tech/icon-tech-claude-mono.svg +5 -0
  263. package/core/icons/tech/icon-tech-claude.svg +3 -0
  264. package/core/icons/tech/icon-tech-jetpack.svg +1 -0
  265. package/core/icons/tech/icon-tech-terraform-outline.svg +5 -0
  266. package/core/images/badges/g2-best-meets-requirements-spring-2025.svg +26 -0
  267. package/core/images/badges/g2-best-results-spring-2025.svg +26 -0
  268. package/core/images/badges/g2-best-support-spring-2025.svg +26 -0
  269. package/core/images/badges/g2-easiest-to-use-spring-2025.svg +26 -0
  270. package/core/images/badges/g2-users-most-likely-to-recommend-spring-2025.svg +26 -0
  271. package/core/images/cust-logo-mentimeter-mono-pos.svg +0 -0
  272. package/core/insights/command-queue.js +1 -1
  273. package/core/insights/command-queue.js.map +1 -1
  274. package/core/insights/datalayer.js +1 -1
  275. package/core/insights/datalayer.js.map +1 -1
  276. package/core/insights/index.js +1 -1
  277. package/core/insights/index.js.map +1 -1
  278. package/core/insights/index.test.js +1 -1
  279. package/core/insights/index.test.js.map +1 -1
  280. package/core/insights/mixpanel.js +1 -1
  281. package/core/insights/mixpanel.js.map +1 -1
  282. package/core/insights/mixpanel.test.js +2 -0
  283. package/core/insights/mixpanel.test.js.map +1 -0
  284. package/core/insights/posthog.js +1 -1
  285. package/core/insights/posthog.js.map +1 -1
  286. package/core/insights/posthog.test.js +2 -0
  287. package/core/insights/posthog.test.js.map +1 -0
  288. package/core/insights/service.js +1 -1
  289. package/core/insights/service.js.map +1 -1
  290. package/core/insights/types.js.map +1 -1
  291. package/core/react-renderer.js.map +1 -1
  292. package/core/sprites-display.svg +1 -1
  293. package/core/sprites-gui.svg +1 -1
  294. package/core/sprites-product.svg +1 -1
  295. package/core/sprites-tech.svg +1 -1
  296. package/core/styles/buttons.css +6 -6
  297. package/core/styles/colors/types.js +1 -1
  298. package/core/styles/colors/types.js.map +1 -1
  299. package/core/styles/forms.css +5 -5
  300. package/core/styles/legacy-buttons.css +8 -8
  301. package/core/styles/properties.css +4 -4
  302. package/core/styles/text.css +2 -2
  303. package/core/styles.components.css +4 -4
  304. package/core/utils/syntax-highlighter.css +31 -0
  305. package/core/utils/syntax-highlighter.js +1 -1
  306. package/core/utils/syntax-highlighter.js.map +1 -1
  307. package/core/utils/syntax-highlighter.test.js +2 -0
  308. package/core/utils/syntax-highlighter.test.js.map +1 -0
  309. package/index.d.ts +1201 -118
  310. package/package.json +66 -59
  311. package/tailwind.config.js +2 -2
  312. package/core/CookieMessage/component.css +0 -15
  313. package/core/CookieMessage.js +0 -2
  314. package/core/CookieMessage.js.map +0 -1
  315. package/core/Icon/components/icon-display-asset-tracking-col.js +0 -2
  316. package/core/Icon/components/icon-display-asset-tracking-col.js.map +0 -1
  317. package/core/Icon/components/icon-gui-prod-asset-tracking-outline.js +0 -2
  318. package/core/Icon/components/icon-gui-prod-asset-tracking-outline.js.map +0 -1
  319. package/core/Icon/components/icon-gui-prod-asset-tracking-solid.js +0 -2
  320. package/core/Icon/components/icon-gui-prod-asset-tracking-solid.js.map +0 -1
  321. package/core/Icon/components/icon-product-asset-tracking-mono.js +0 -2
  322. package/core/Icon/components/icon-product-asset-tracking-mono.js.map +0 -1
  323. package/core/Icon/components/icon-product-asset-tracking.js +0 -2
  324. package/core/Icon/components/icon-product-asset-tracking.js.map +0 -1
  325. package/core/Meganav/MeganavProductTile.js +0 -2
  326. package/core/Meganav/MeganavProductTile.js.map +0 -1
  327. package/core/Meganav/images/fan-engagement-nav-image.png +0 -0
  328. package/core/Meganav/images/founders-nav-image.png +0 -0
  329. package/core/icons/display/icon-display-asset-tracking-col.svg +0 -18
  330. package/core/icons/gui/icon-gui-prod-asset-tracking-outline.svg +0 -3
  331. package/core/icons/gui/icon-gui-prod-asset-tracking-solid.svg +0 -3
  332. package/core/icons/product/icon-product-asset-tracking-mono.svg +0 -3
  333. package/core/icons/product/icon-product-asset-tracking.svg +0 -12
  334. package/core/images/g2-best-meets-requirements-2025.svg +0 -10
  335. package/core/images/g2-best-support-2025.svg +0 -10
  336. package/core/images/g2-high-performer-2025.svg +0 -9
  337. package/core/images/g2-users-most-likely-to-recommend-2025.svg +0 -10
  338. package/core/utils/useCopyToClipboard.js +0 -2
  339. package/core/utils/useCopyToClipboard.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/ApiKeySelector.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport * as Select from \"@radix-ui/react-select\";\nimport Badge from \"../Badge\";\nimport Icon from \"../Icon\";\nimport Tooltip from \"../Tooltip\";\nimport type { ApiKeysItem } from \"../CodeSnippet\";\n\ntype ApiKeySelectorProps = {\n apiKeys?: ApiKeysItem[];\n selectedApiKey: string;\n onApiKeyChange: (apiKey: string) => void;\n};\n\nconst ApiKeySelector = ({\n apiKeys,\n selectedApiKey,\n onApiKeyChange,\n}: ApiKeySelectorProps) => {\n const isDemoMode = useMemo(\n () => apiKeys?.length === 1 && apiKeys[0].app === \"demo\",\n [apiKeys],\n );\n\n // Render the demo mode UI\n const renderDemoMode = useMemo(\n () => (\n <div className=\"flex items-center gap-2\">\n <Badge className=\"ml-1 bg-neutral-200 dark:bg-neutral-1100\">\n DEMO ONLY\n </Badge>\n <Tooltip\n className=\"ml-0\"\n triggerElement={\n <Icon\n name=\"icon-gui-information-circle-outline\"\n size=\"16px\"\n color=\"text-neutral-700 dark:text-neutral-600\"\n />\n }\n >\n This code example uses a temporary key that is rate limited and\n expires in 4 hrs. Sign in to Ably to use your API keys instead.\n </Tooltip>\n </div>\n ),\n [],\n );\n\n // Render the dropdown only if we have API keys\n const renderApiKeyDropdown = useMemo(() => {\n if (isDemoMode) {\n return renderDemoMode;\n }\n\n if (!apiKeys?.length) {\n return null;\n }\n\n return (\n <Select.Root value={selectedApiKey} onValueChange={onApiKeyChange}>\n <Select.Trigger\n className=\"font-sans inline-flex items-center justify-between rounded px-3 py-2 ml-1 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-2 focus-base border\"\n aria-label=\"API Key\"\n >\n <Select.Value />\n <Select.Icon className=\"size-4\">\n <Icon name=\"icon-gui-chevron-down-micro\" size=\"16px\" />\n </Select.Icon>\n </Select.Trigger>\n\n <Select.Portal>\n <Select.Content className=\"overflow-hidden rounded-lg bg-neutral-000 dark:bg-neutral-1300 border border-neutral-200 dark:border-neutral-1000 shadow-md z-50\">\n <Select.ScrollUpButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon\n name=\"icon-gui-chevron-down-outline\"\n size=\"16px\"\n additionalCSS=\"rotate-180\"\n />\n </Select.ScrollUpButton>\n\n <Select.Viewport className=\"rounded-lg font-sans\">\n {apiKeys.map((apiKeyItem) => (\n <Select.Group key={apiKeyItem.app}>\n {apiKeys.length > 1 && (\n <Select.Label className=\"text-neutral-700 rounded-none dark:text-neutral-600 p-1 bg-neutral-200 dark:bg-neutral-1100\">\n {apiKeyItem.app}\n </Select.Label>\n )}\n {apiKeyItem.keys.map(({ name, key }) => (\n <Select.Item\n key={`${apiKeyItem.app}-${name}-${key}`}\n value={key}\n className=\"relative flex items-center justify-between m-2 p-2 rounded-lg text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base min-w-64\"\n >\n <Select.ItemText>\n {key.length > 10 ? `${key.substring(0, 10)}...` : key}\n <span className=\"font-light\">\n {name && ` - ${name}`}\n </span>\n </Select.ItemText>\n <Select.ItemIndicator className=\"size-4\">\n <Icon name=\"icon-gui-check-micro\" size=\"16px\" />\n </Select.ItemIndicator>\n </Select.Item>\n ))}\n </Select.Group>\n ))}\n </Select.Viewport>\n\n <Select.ScrollDownButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon name=\"icon-gui-chevron-down-outline\" size=\"16px\" />\n </Select.ScrollDownButton>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n }, [apiKeys, isDemoMode, selectedApiKey, onApiKeyChange, renderDemoMode]);\n\n return (\n <div className=\"flex items-center border-t border-neutral-200 dark:border-neutral-1100 px-3 py-3\">\n <span className=\"ui-text-label4 text-neutral-700 dark:text-neutral-600 mr-1\">\n API key:\n </span>\n {renderApiKeyDropdown}\n </div>\n );\n};\n\n// Define a display name to improve debugging\nApiKeySelector.displayName = \"ApiKeySelector\";\n\nexport default ApiKeySelector;\n"],"names":["React","useMemo","Select","Badge","Icon","Tooltip","ApiKeySelector","apiKeys","selectedApiKey","onApiKeyChange","isDemoMode","length","app","renderDemoMode","div","className","triggerElement","name","size","color","renderApiKeyDropdown","Root","value","onValueChange","Trigger","aria-label","Value","Portal","Content","ScrollUpButton","additionalCSS","Viewport","map","apiKeyItem","Group","key","Label","keys","Item","ItemText","substring","span","ItemIndicator","ScrollDownButton","displayName"],"mappings":"AAAA,OAAOA,OAASC,OAAO,KAAQ,OAAQ,AACvC,WAAYC,WAAY,wBAAyB,AACjD,QAAOC,UAAW,UAAW,AAC7B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,YAAa,YAAa,CASjC,MAAMC,eAAiB,CAAC,CACtBC,OAAO,CACPC,cAAc,CACdC,cAAc,CACM,IACpB,MAAMC,WAAaT,QACjB,IAAMM,SAASI,SAAW,GAAKJ,OAAO,CAAC,EAAE,CAACK,GAAG,GAAK,OAClD,CAACL,QAAQ,EAIX,MAAMM,eAAiBZ,QACrB,IACE,oBAACa,OAAIC,UAAU,2BACb,oBAACZ,OAAMY,UAAU,4CAA2C,aAG5D,oBAACV,SACCU,UAAU,OACVC,eACE,oBAACZ,MACCa,KAAK,sCACLC,KAAK,OACLC,MAAM,4CAGX,oIAML,EAAE,EAIJ,MAAMC,qBAAuBnB,QAAQ,KACnC,GAAIS,WAAY,CACd,OAAOG,cACT,CAEA,GAAI,CAACN,SAASI,OAAQ,CACpB,OAAO,IACT,CAEA,OACE,oBAACT,OAAOmB,IAAI,EAACC,MAAOd,eAAgBe,cAAed,gBACjD,oBAACP,OAAOsB,OAAO,EACbT,UAAU,wOACVU,aAAW,WAEX,oBAACvB,OAAOwB,KAAK,OACb,oBAACxB,OAAOE,IAAI,EAACW,UAAU,UACrB,oBAACX,MAAKa,KAAK,8BAA8BC,KAAK,WAIlD,oBAAChB,OAAOyB,MAAM,MACZ,oBAACzB,OAAO0B,OAAO,EAACb,UAAU,oIACxB,oBAACb,OAAO2B,cAAc,EAACd,UAAU,8IAC/B,oBAACX,MACCa,KAAK,gCACLC,KAAK,OACLY,cAAc,gBAIlB,oBAAC5B,OAAO6B,QAAQ,EAAChB,UAAU,wBACxBR,QAAQyB,GAAG,CAAC,AAACC,YACZ,oBAAC/B,OAAOgC,KAAK,EAACC,IAAKF,WAAWrB,GAAG,EAC9BL,QAAQI,MAAM,CAAG,GAChB,oBAACT,OAAOkC,KAAK,EAACrB,UAAU,+FACrBkB,WAAWrB,GAAG,EAGlBqB,WAAWI,IAAI,CAACL,GAAG,CAAC,CAAC,CAAEf,IAAI,CAAEkB,GAAG,CAAE,GACjC,oBAACjC,OAAOoC,IAAI,EACVH,IAAK,CAAC,EAAEF,WAAWrB,GAAG,CAAC,CAAC,EAAEK,KAAK,CAAC,EAAEkB,IAAI,CAAC,CACvCb,MAAOa,IACPpB,UAAU,2SAEV,oBAACb,OAAOqC,QAAQ,MACbJ,IAAIxB,MAAM,CAAG,GAAK,CAAC,EAAEwB,IAAIK,SAAS,CAAC,EAAG,IAAI,GAAG,CAAC,CAAGL,IAClD,oBAACM,QAAK1B,UAAU,cACbE,MAAQ,CAAC,GAAG,EAAEA,KAAK,CAAC,GAGzB,oBAACf,OAAOwC,aAAa,EAAC3B,UAAU,UAC9B,oBAACX,MAAKa,KAAK,uBAAuBC,KAAK,eAQnD,oBAAChB,OAAOyC,gBAAgB,EAAC5B,UAAU,8IACjC,oBAACX,MAAKa,KAAK,gCAAgCC,KAAK,YAM5D,EAAG,CAACX,QAASG,WAAYF,eAAgBC,eAAgBI,eAAe,EAExE,OACE,oBAACC,OAAIC,UAAU,oFACb,oBAAC0B,QAAK1B,UAAU,8DAA6D,YAG5EK,qBAGP,CAGAd,CAAAA,eAAesC,WAAW,CAAG,gBAE7B,gBAAetC,cAAe"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/ApiKeySelector.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport * as Select from \"@radix-ui/react-select\";\nimport Badge from \"../Badge\";\nimport Icon from \"../Icon\";\nimport Tooltip from \"../Tooltip\";\nimport type { ApiKeysItem } from \"../CodeSnippet\";\n\ntype ApiKeySelectorProps = {\n apiKeys?: ApiKeysItem[];\n selectedApiKey: string;\n onApiKeyChange: (apiKey: string) => void;\n};\n\nconst ApiKeySelector = ({\n apiKeys,\n selectedApiKey,\n onApiKeyChange,\n}: ApiKeySelectorProps) => {\n const isDemoMode = useMemo(\n () => apiKeys?.length === 1 && apiKeys[0].app === \"demo\",\n [apiKeys],\n );\n\n const renderDemoMode = useMemo(\n () => (\n <div className=\"flex items-center gap-2\">\n <Badge className=\"ml-1 bg-neutral-200 dark:bg-neutral-1100\">\n DEMO ONLY\n </Badge>\n <Tooltip\n className=\"ml-0\"\n triggerProps={{\n className: \"h-5\",\n }}\n contentProps={{\n className:\n \"bg-neutral-1100 dark:bg-neutral-200 text-neutral-300 dark:text-neutral-1000\",\n }}\n triggerElement={\n <div className=\"group/code-snippet-tooltip-icon-hover flex items-center justify-center\">\n <Icon\n name=\"icon-gui-information-circle-outline\"\n size=\"20px\"\n color=\"text-neutral-700 dark:text-neutral-600\"\n additionalCSS=\"group-hover/code-snippet-tooltip-icon-hover:hidden\"\n />\n <Icon\n name=\"icon-gui-information-circle-solid\"\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n additionalCSS=\"group-hover/code-snippet-tooltip-icon-hover:flex hidden\"\n />\n </div>\n }\n >\n This code example uses a temporary key that is rate limited and\n expires in 4 hrs. Sign in to Ably to use your API keys instead.\n </Tooltip>\n </div>\n ),\n [],\n );\n\n const renderApiKeyDropdown = useMemo(() => {\n if (isDemoMode) {\n return renderDemoMode;\n }\n\n if (!apiKeys?.length) {\n return null;\n }\n\n return (\n <Select.Root value={selectedApiKey} onValueChange={onApiKeyChange}>\n <Select.Trigger\n className=\"font-sans inline-flex items-center justify-between rounded px-3 py-2 ml-1 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-2 focus-base border border-neutral-300 dark:border-neutral-1000 transition-colors\"\n aria-label=\"API Key\"\n >\n <Select.Value />\n <Select.Icon className=\"size-4\">\n <Icon name=\"icon-gui-chevron-down-micro\" size=\"16px\" />\n </Select.Icon>\n </Select.Trigger>\n\n <Select.Portal>\n <Select.Content className=\"overflow-hidden rounded-lg bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 shadow-md z-50\">\n <Select.ScrollUpButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon\n name=\"icon-gui-chevron-down-outline\"\n size=\"16px\"\n additionalCSS=\"rotate-180\"\n />\n </Select.ScrollUpButton>\n\n <Select.Viewport className=\"rounded-lg font-sans\">\n {apiKeys.map((apiKeyItem) => (\n <Select.Group key={apiKeyItem.app}>\n {apiKeys.length > 1 && (\n <Select.Label className=\"text-neutral-700 rounded-none dark:text-neutral-600 p-1 bg-neutral-200 dark:bg-neutral-1100\">\n {apiKeyItem.app}\n </Select.Label>\n )}\n {apiKeyItem.keys.map(({ name, key }) => (\n <Select.Item\n key={`${apiKeyItem.app}-${name}-${key}`}\n value={key}\n className=\"relative flex items-center justify-between m-2 p-2 rounded-lg text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base min-w-64\"\n >\n <Select.ItemText>\n {key.length > 10 ? `${key.substring(0, 10)}...` : key}\n <span className=\"font-light\">\n {name && ` - ${name}`}\n </span>\n </Select.ItemText>\n <Select.ItemIndicator className=\"size-4\">\n <Icon name=\"icon-gui-check-micro\" size=\"16px\" />\n </Select.ItemIndicator>\n </Select.Item>\n ))}\n </Select.Group>\n ))}\n </Select.Viewport>\n\n <Select.ScrollDownButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon name=\"icon-gui-chevron-down-outline\" size=\"16px\" />\n </Select.ScrollDownButton>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n }, [apiKeys, isDemoMode, selectedApiKey, onApiKeyChange, renderDemoMode]);\n\n return (\n <div className=\"flex items-center border-t border-neutral-300 dark:border-neutral-1000 px-3 py-3\">\n <span className=\"ui-text-label4 text-neutral-700 dark:text-neutral-600 mr-1\">\n API key:\n </span>\n {renderApiKeyDropdown}\n </div>\n );\n};\n\nexport default ApiKeySelector;\n"],"names":["React","useMemo","Select","Badge","Icon","Tooltip","ApiKeySelector","apiKeys","selectedApiKey","onApiKeyChange","isDemoMode","length","app","renderDemoMode","div","className","triggerProps","contentProps","triggerElement","name","size","color","additionalCSS","renderApiKeyDropdown","Root","value","onValueChange","Trigger","aria-label","Value","Portal","Content","ScrollUpButton","Viewport","map","apiKeyItem","Group","key","Label","keys","Item","ItemText","substring","span","ItemIndicator","ScrollDownButton"],"mappings":"AAAA,OAAOA,OAASC,OAAO,KAAQ,OAAQ,AACvC,WAAYC,WAAY,wBAAyB,AACjD,QAAOC,UAAW,UAAW,AAC7B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,YAAa,YAAa,CASjC,MAAMC,eAAiB,CAAC,CACtBC,OAAO,CACPC,cAAc,CACdC,cAAc,CACM,IACpB,MAAMC,WAAaT,QACjB,IAAMM,SAASI,SAAW,GAAKJ,OAAO,CAAC,EAAE,CAACK,GAAG,GAAK,OAClD,CAACL,QAAQ,EAGX,MAAMM,eAAiBZ,QACrB,IACE,oBAACa,OAAIC,UAAU,2BACb,oBAACZ,OAAMY,UAAU,4CAA2C,aAG5D,oBAACV,SACCU,UAAU,OACVC,aAAc,CACZD,UAAW,KACb,EACAE,aAAc,CACZF,UACE,6EACJ,EACAG,eACE,oBAACJ,OAAIC,UAAU,0EACb,oBAACX,MACCe,KAAK,sCACLC,KAAK,OACLC,MAAM,yCACNC,cAAc,uDAEhB,oBAAClB,MACCe,KAAK,oCACLC,KAAK,OACLC,MAAM,0CACNC,cAAc,8DAIrB,oIAML,EAAE,EAGJ,MAAMC,qBAAuBtB,QAAQ,KACnC,GAAIS,WAAY,CACd,OAAOG,cACT,CAEA,GAAI,CAACN,SAASI,OAAQ,CACpB,OAAO,IACT,CAEA,OACE,oBAACT,OAAOsB,IAAI,EAACC,MAAOjB,eAAgBkB,cAAejB,gBACjD,oBAACP,OAAOyB,OAAO,EACbZ,UAAU,sSACVa,aAAW,WAEX,oBAAC1B,OAAO2B,KAAK,OACb,oBAAC3B,OAAOE,IAAI,EAACW,UAAU,UACrB,oBAACX,MAAKe,KAAK,8BAA8BC,KAAK,WAIlD,oBAAClB,OAAO4B,MAAM,MACZ,oBAAC5B,OAAO6B,OAAO,EAAChB,UAAU,oIACxB,oBAACb,OAAO8B,cAAc,EAACjB,UAAU,8IAC/B,oBAACX,MACCe,KAAK,gCACLC,KAAK,OACLE,cAAc,gBAIlB,oBAACpB,OAAO+B,QAAQ,EAAClB,UAAU,wBACxBR,QAAQ2B,GAAG,CAAC,AAACC,YACZ,oBAACjC,OAAOkC,KAAK,EAACC,IAAKF,WAAWvB,GAAG,EAC9BL,QAAQI,MAAM,CAAG,GAChB,oBAACT,OAAOoC,KAAK,EAACvB,UAAU,+FACrBoB,WAAWvB,GAAG,EAGlBuB,WAAWI,IAAI,CAACL,GAAG,CAAC,CAAC,CAAEf,IAAI,CAAEkB,GAAG,CAAE,GACjC,oBAACnC,OAAOsC,IAAI,EACVH,IAAK,CAAC,EAAEF,WAAWvB,GAAG,CAAC,CAAC,EAAEO,KAAK,CAAC,EAAEkB,IAAI,CAAC,CACvCZ,MAAOY,IACPtB,UAAU,2SAEV,oBAACb,OAAOuC,QAAQ,MACbJ,IAAI1B,MAAM,CAAG,GAAK,CAAC,EAAE0B,IAAIK,SAAS,CAAC,EAAG,IAAI,GAAG,CAAC,CAAGL,IAClD,oBAACM,QAAK5B,UAAU,cACbI,MAAQ,CAAC,GAAG,EAAEA,KAAK,CAAC,GAGzB,oBAACjB,OAAO0C,aAAa,EAAC7B,UAAU,UAC9B,oBAACX,MAAKe,KAAK,uBAAuBC,KAAK,eAQnD,oBAAClB,OAAO2C,gBAAgB,EAAC9B,UAAU,8IACjC,oBAACX,MAAKe,KAAK,gCAAgCC,KAAK,YAM5D,EAAG,CAACb,QAASG,WAAYF,eAAgBC,eAAgBI,eAAe,EAExE,OACE,oBAACC,OAAIC,UAAU,oFACb,oBAAC4B,QAAK5B,UAAU,8DAA6D,YAG5EQ,qBAGP,CAEA,gBAAejB,cAAe"}
@@ -0,0 +1,2 @@
1
+ import React from"react";import{describe,expect,it,vi,afterEach}from"vitest";import{render,screen,within,cleanup}from"@testing-library/react";import CodeSnippet from"../CodeSnippet";afterEach(cleanup);vi.mock("../Code",()=>({default:({snippet,language})=>React.createElement("div",{"data-testid":"code-block","data-language":language},snippet)}));vi.mock("../Icon",()=>({default:({name})=>React.createElement("span",{"data-testid":"icon","data-icon":name})}));vi.mock("../SegmentedControl",()=>({default:({children,onClick,active})=>React.createElement("button",{"data-testid":"sdk-toggle","data-active":active,onClick:onClick},children)}));vi.mock("./LanguageSelector",()=>({default:({languages,activeLanguage,onLanguageChange})=>React.createElement("div",{"data-testid":"language-selector","data-active":activeLanguage},languages.map(lang=>React.createElement("button",{key:lang,"data-testid":`lang-${lang}`,onClick:()=>onLanguageChange(lang)},lang)))}));vi.mock("./CopyButton",()=>({default:()=>React.createElement("button",{"data-testid":"copy-button"},"Copy")}));vi.mock("./ApiKeySelector",()=>({default:()=>React.createElement("div",{"data-testid":"api-key-selector"})}));vi.mock("./PlainCodeView",()=>({default:({content,language})=>React.createElement("div",{"data-testid":"plain-code-view","data-language":language},content)}));const makeSnippet=(lang,content)=>React.createElement("pre",null,React.createElement("code",{className:`language-${lang}`},content));describe("CodeSnippet",()=>{describe("basic rendering",()=>{it("renders a single language snippet",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},makeSnippet("javascript","console.log('hello')")));expect(screen.getByTestId("code-block").textContent).toBe("console.log('hello')")});it("renders a language label for a single non-fixed language",()=>{const{container}=render(React.createElement(CodeSnippet,{lang:"javascript"},makeSnippet("javascript","const x = 1;")));const labelSpans=container.querySelectorAll(".ui-text-label4");const labels=Array.from(labelSpans).map(el=>el.textContent);expect(labels).toContain("JavaScript")});it("renders the language selector when multiple languages are available",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},makeSnippet("javascript","const x = 1;"),makeSnippet("python","x = 1")));expect(screen.getByTestId("language-selector")).toBeTruthy()})});describe("realtime/rest SDK types",()=>{it("shows SDK selector for realtime/rest prefixed languages",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime"},makeSnippet("realtime_javascript","// realtime code"),makeSnippet("rest_javascript","// rest code")));const toggles=screen.getAllByTestId("sdk-toggle");expect(toggles).toHaveLength(2);expect(toggles[0].textContent).toBe("Realtime");expect(toggles[1].textContent).toBe("REST")});it("shows single SDK label when only one SDK type present",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime"},makeSnippet("realtime_javascript","// realtime only")));const toggles=screen.getAllByTestId("sdk-toggle");expect(toggles[0].textContent).toBe("Realtime")});it("resolves to the correct SDK when only one type is available",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime"},makeSnippet("rest_javascript","// rest only")));expect(screen.getByTestId("code-block").textContent).toBe("// rest only")})});describe("client/agent SDK types",()=>{it("does not show SDK selector for client/agent prefixed languages",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"client",fixed:true},makeSnippet("client_javascript","// client code"),makeSnippet("agent_python","// agent code")));expect(screen.queryAllByTestId("sdk-toggle")).toHaveLength(0)});it("renders client_ prefixed snippet with fixed mode and sdk=client",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"client",fixed:true},makeSnippet("client_javascript","// client JS"),makeSnippet("agent_python","// agent python")));expect(screen.getByTestId("code-block").textContent).toBe("// client JS")});it("renders agent_ prefixed snippet with fixed mode and sdk=agent",()=>{render(React.createElement(CodeSnippet,{lang:"python",sdk:"agent",fixed:true},makeSnippet("client_javascript","// client JS"),makeSnippet("agent_python","// agent python")));expect(screen.getByTestId("code-block").textContent).toBe("// agent python")});it("falls back to first language with matching prefix when exact match not found",()=>{render(React.createElement(CodeSnippet,{lang:"ruby",sdk:"client",fixed:true},makeSnippet("client_javascript","// client JS"),makeSnippet("client_typescript","// client TS")));expect(screen.getByTestId("code-block").textContent).toBe("// client JS")})});describe("fixed mode",()=>{it("shows a read-only language label in fixed mode",()=>{const{container}=render(React.createElement(CodeSnippet,{lang:"javascript",fixed:true},makeSnippet("javascript","const x = 1;")));const labelSpans=container.querySelectorAll(".ui-text-label4");const labels=Array.from(labelSpans).map(el=>el.textContent);expect(labels).toContain("JavaScript");expect(screen.queryByTestId("language-selector")).toBeNull()});it("shows correct label for client_ prefixed language in fixed mode",()=>{const{container}=render(React.createElement(CodeSnippet,{lang:"python",sdk:"client",fixed:true},makeSnippet("client_python","# client python")));const labelSpans=container.querySelectorAll(".ui-text-label4");const labels=Array.from(labelSpans).map(el=>el.textContent);expect(labels).toContain("Python")});it("hides language selector in fixed mode even with multiple languages",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",fixed:true},makeSnippet("javascript","const x = 1;"),makeSnippet("python","x = 1")));expect(screen.queryByTestId("language-selector")).toBeNull()})});describe("header row",()=>{it("renders a header row when headerRow is true",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",headerRow:true,title:"My Code"},makeSnippet("javascript","const x = 1;")));expect(screen.getByText("My Code")).toBeTruthy()})});describe("plain command mode",()=>{it("renders shell commands in plain mode",()=>{render(React.createElement(CodeSnippet,{lang:"shell"},makeSnippet("shell","npm install")));expect(screen.getByTestId("plain-code-view").textContent).toBe("npm install")});it("renders text commands in plain mode",()=>{render(React.createElement(CodeSnippet,{lang:"text"},makeSnippet("text","Hello world")));expect(screen.getByTestId("plain-code-view").textContent).toBe("Hello world")})});describe("onChange callback",()=>{it("passes stripped language and sdk type on language change",()=>{const onChange=vi.fn();render(React.createElement(CodeSnippet,{lang:"javascript",sdk:"realtime",onChange:onChange},makeSnippet("realtime_javascript","// js code"),makeSnippet("realtime_python","# python code")));const pyButton=screen.getByTestId("lang-realtime_python");pyButton.click();expect(onChange).toHaveBeenCalledWith("python","realtime")});it("passes undefined sdk when no SDK type",()=>{const onChange=vi.fn();render(React.createElement(CodeSnippet,{lang:"javascript",onChange:onChange},makeSnippet("javascript","// js"),makeSnippet("python","# py")));const pyButton=screen.getByTestId("lang-python");pyButton.click();expect(onChange).toHaveBeenCalledWith("python",undefined)})});describe("missing language snippet",()=>{it("shows a message when active language has no snippet",()=>{render(React.createElement(CodeSnippet,{lang:"ruby"},makeSnippet("javascript","const x = 1;"),makeSnippet("python","x = 1")));expect(screen.getByText(/currently viewing the Ruby docs/)).toBeTruthy()})});describe("findCodeElement handling",()=>{it("extracts code from pre with a single code child",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},React.createElement("pre",null,React.createElement("code",{className:"language-javascript"},"console.log('single')"))));expect(screen.getByTestId("code-block").textContent).toBe("console.log('single')")});it("extracts code from pre with multiple children (array)",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},React.createElement("pre",null,"\n",React.createElement("code",{className:"language-javascript"},"console.log('array')"),"\n")));expect(screen.getByTestId("code-block").textContent).toBe("console.log('array')")});it("handles multiple snippets where pre has array children",()=>{render(React.createElement(CodeSnippet,{lang:"javascript"},React.createElement("pre",null,"\n",React.createElement("code",{className:"language-javascript"},"// js code")),React.createElement("pre",null,"\n",React.createElement("code",{className:"language-python"},"# py code"))));expect(screen.getByTestId("language-selector")).toBeTruthy();expect(screen.getByTestId("code-block").textContent).toBe("// js code")})});describe("JSON-only snippets",()=>{it("always shows JSON content regardless of selected language",()=>{render(React.createElement(CodeSnippet,{lang:"ruby"},makeSnippet("json",'{"key": "value"}')));expect(screen.getByTestId("code-block").textContent).toBe('{"key": "value"}')})});describe("language ordering",()=>{it("respects custom language ordering",()=>{render(React.createElement(CodeSnippet,{lang:"javascript",languageOrdering:["python","typescript","javascript"]},makeSnippet("javascript","// js"),makeSnippet("typescript","// ts"),makeSnippet("python","# py")));const selector=screen.getByTestId("language-selector");const buttons=within(selector).getAllByRole("button");expect(buttons[0].textContent).toBe("python");expect(buttons[1].textContent).toBe("typescript");expect(buttons[2].textContent).toBe("javascript")})})});
2
+ //# sourceMappingURL=CodeSnippet.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/CodeSnippet.test.tsx"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\n\nimport React from \"react\";\nimport { describe, expect, it, vi, afterEach } from \"vitest\";\nimport { render, screen, within, cleanup } from \"@testing-library/react\";\n\nimport CodeSnippet from \"../CodeSnippet\";\n\nafterEach(cleanup);\n\n// Mock child components to avoid complex rendering dependencies\nvi.mock(\"../Code\", () => ({\n default: ({ snippet, language }: { snippet: string; language: string }) => (\n <div data-testid=\"code-block\" data-language={language}>\n {snippet}\n </div>\n ),\n}));\n\nvi.mock(\"../Icon\", () => ({\n default: ({ name }: { name: string }) => (\n <span data-testid=\"icon\" data-icon={name} />\n ),\n}));\n\nvi.mock(\"../SegmentedControl\", () => ({\n default: ({\n children,\n onClick,\n active,\n }: {\n children: React.ReactNode;\n onClick: () => void;\n active: boolean;\n }) => (\n <button data-testid=\"sdk-toggle\" data-active={active} onClick={onClick}>\n {children}\n </button>\n ),\n}));\n\nvi.mock(\"./LanguageSelector\", () => ({\n default: ({\n languages,\n activeLanguage,\n onLanguageChange,\n }: {\n languages: string[];\n activeLanguage: string;\n onLanguageChange: (lang: string) => void;\n }) => (\n <div data-testid=\"language-selector\" data-active={activeLanguage}>\n {languages.map((lang) => (\n <button\n key={lang}\n data-testid={`lang-${lang}`}\n onClick={() => onLanguageChange(lang)}\n >\n {lang}\n </button>\n ))}\n </div>\n ),\n}));\n\nvi.mock(\"./CopyButton\", () => ({\n default: () => <button data-testid=\"copy-button\">Copy</button>,\n}));\n\nvi.mock(\"./ApiKeySelector\", () => ({\n default: () => <div data-testid=\"api-key-selector\" />,\n}));\n\nvi.mock(\"./PlainCodeView\", () => ({\n default: ({ content, language }: { content: string; language: string }) => (\n <div data-testid=\"plain-code-view\" data-language={language}>\n {content}\n </div>\n ),\n}));\n\nconst makeSnippet = (lang: string, content: string) => (\n <pre>\n <code className={`language-${lang}`}>{content}</code>\n </pre>\n);\n\ndescribe(\"CodeSnippet\", () => {\n describe(\"basic rendering\", () => {\n it(\"renders a single language snippet\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n {makeSnippet(\"javascript\", \"console.log('hello')\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n \"console.log('hello')\",\n );\n });\n\n it(\"renders a language label for a single non-fixed language\", () => {\n const { container } = render(\n <CodeSnippet lang=\"javascript\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n </CodeSnippet>,\n );\n const labelSpans = container.querySelectorAll(\".ui-text-label4\");\n const labels = Array.from(labelSpans).map((el) => el.textContent);\n expect(labels).toContain(\"JavaScript\");\n });\n\n it(\"renders the language selector when multiple languages are available\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n {makeSnippet(\"python\", \"x = 1\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"language-selector\")).toBeTruthy();\n });\n });\n\n describe(\"realtime/rest SDK types\", () => {\n it(\"shows SDK selector for realtime/rest prefixed languages\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\">\n {makeSnippet(\"realtime_javascript\", \"// realtime code\")}\n {makeSnippet(\"rest_javascript\", \"// rest code\")}\n </CodeSnippet>,\n );\n const toggles = screen.getAllByTestId(\"sdk-toggle\");\n expect(toggles).toHaveLength(2);\n expect(toggles[0].textContent).toBe(\"Realtime\");\n expect(toggles[1].textContent).toBe(\"REST\");\n });\n\n it(\"shows single SDK label when only one SDK type present\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\">\n {makeSnippet(\"realtime_javascript\", \"// realtime only\")}\n </CodeSnippet>,\n );\n const toggles = screen.getAllByTestId(\"sdk-toggle\");\n expect(toggles[0].textContent).toBe(\"Realtime\");\n });\n\n it(\"resolves to the correct SDK when only one type is available\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\">\n {makeSnippet(\"rest_javascript\", \"// rest only\")}\n </CodeSnippet>,\n );\n // Should fall back to rest since that's the only type available\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// rest only\");\n });\n });\n\n describe(\"client/agent SDK types\", () => {\n it(\"does not show SDK selector for client/agent prefixed languages\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"client\" fixed>\n {makeSnippet(\"client_javascript\", \"// client code\")}\n {makeSnippet(\"agent_python\", \"// agent code\")}\n </CodeSnippet>,\n );\n expect(screen.queryAllByTestId(\"sdk-toggle\")).toHaveLength(0);\n });\n\n it(\"renders client_ prefixed snippet with fixed mode and sdk=client\", () => {\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"client\" fixed>\n {makeSnippet(\"client_javascript\", \"// client JS\")}\n {makeSnippet(\"agent_python\", \"// agent python\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// client JS\");\n });\n\n it(\"renders agent_ prefixed snippet with fixed mode and sdk=agent\", () => {\n render(\n <CodeSnippet lang=\"python\" sdk=\"agent\" fixed>\n {makeSnippet(\"client_javascript\", \"// client JS\")}\n {makeSnippet(\"agent_python\", \"// agent python\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n \"// agent python\",\n );\n });\n\n it(\"falls back to first language with matching prefix when exact match not found\", () => {\n render(\n <CodeSnippet lang=\"ruby\" sdk=\"client\" fixed>\n {makeSnippet(\"client_javascript\", \"// client JS\")}\n {makeSnippet(\"client_typescript\", \"// client TS\")}\n </CodeSnippet>,\n );\n // Ruby doesn't exist with client_ prefix, should fall back to first client_ language\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// client JS\");\n });\n });\n\n describe(\"fixed mode\", () => {\n it(\"shows a read-only language label in fixed mode\", () => {\n const { container } = render(\n <CodeSnippet lang=\"javascript\" fixed>\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n </CodeSnippet>,\n );\n const labelSpans = container.querySelectorAll(\".ui-text-label4\");\n const labels = Array.from(labelSpans).map((el) => el.textContent);\n expect(labels).toContain(\"JavaScript\");\n expect(screen.queryByTestId(\"language-selector\")).toBeNull();\n });\n\n it(\"shows correct label for client_ prefixed language in fixed mode\", () => {\n const { container } = render(\n <CodeSnippet lang=\"python\" sdk=\"client\" fixed>\n {makeSnippet(\"client_python\", \"# client python\")}\n </CodeSnippet>,\n );\n const labelSpans = container.querySelectorAll(\".ui-text-label4\");\n const labels = Array.from(labelSpans).map((el) => el.textContent);\n expect(labels).toContain(\"Python\");\n });\n\n it(\"hides language selector in fixed mode even with multiple languages\", () => {\n render(\n <CodeSnippet lang=\"javascript\" fixed>\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n {makeSnippet(\"python\", \"x = 1\")}\n </CodeSnippet>,\n );\n expect(screen.queryByTestId(\"language-selector\")).toBeNull();\n });\n });\n\n describe(\"header row\", () => {\n it(\"renders a header row when headerRow is true\", () => {\n render(\n <CodeSnippet lang=\"javascript\" headerRow title=\"My Code\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n </CodeSnippet>,\n );\n expect(screen.getByText(\"My Code\")).toBeTruthy();\n });\n });\n\n describe(\"plain command mode\", () => {\n it(\"renders shell commands in plain mode\", () => {\n render(\n <CodeSnippet lang=\"shell\">\n {makeSnippet(\"shell\", \"npm install\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"plain-code-view\").textContent).toBe(\n \"npm install\",\n );\n });\n\n it(\"renders text commands in plain mode\", () => {\n render(\n <CodeSnippet lang=\"text\">\n {makeSnippet(\"text\", \"Hello world\")}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"plain-code-view\").textContent).toBe(\n \"Hello world\",\n );\n });\n });\n\n describe(\"onChange callback\", () => {\n it(\"passes stripped language and sdk type on language change\", () => {\n const onChange = vi.fn();\n render(\n <CodeSnippet lang=\"javascript\" sdk=\"realtime\" onChange={onChange}>\n {makeSnippet(\"realtime_javascript\", \"// js code\")}\n {makeSnippet(\"realtime_python\", \"# python code\")}\n </CodeSnippet>,\n );\n const pyButton = screen.getByTestId(\"lang-realtime_python\");\n pyButton.click();\n expect(onChange).toHaveBeenCalledWith(\"python\", \"realtime\");\n });\n\n it(\"passes undefined sdk when no SDK type\", () => {\n const onChange = vi.fn();\n render(\n <CodeSnippet lang=\"javascript\" onChange={onChange}>\n {makeSnippet(\"javascript\", \"// js\")}\n {makeSnippet(\"python\", \"# py\")}\n </CodeSnippet>,\n );\n const pyButton = screen.getByTestId(\"lang-python\");\n pyButton.click();\n expect(onChange).toHaveBeenCalledWith(\"python\", undefined);\n });\n });\n\n describe(\"missing language snippet\", () => {\n it(\"shows a message when active language has no snippet\", () => {\n render(\n <CodeSnippet lang=\"ruby\">\n {makeSnippet(\"javascript\", \"const x = 1;\")}\n {makeSnippet(\"python\", \"x = 1\")}\n </CodeSnippet>,\n );\n expect(screen.getByText(/currently viewing the Ruby docs/)).toBeTruthy();\n });\n });\n\n describe(\"findCodeElement handling\", () => {\n it(\"extracts code from pre with a single code child\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n <pre>\n <code className=\"language-javascript\">\n console.log(&apos;single&apos;)\n </code>\n </pre>\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n \"console.log('single')\",\n );\n });\n\n it(\"extracts code from pre with multiple children (array)\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n <pre>\n {\"\\n\"}\n <code className=\"language-javascript\">\n console.log(&apos;array&apos;)\n </code>\n {\"\\n\"}\n </pre>\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n \"console.log('array')\",\n );\n });\n\n it(\"handles multiple snippets where pre has array children\", () => {\n render(\n <CodeSnippet lang=\"javascript\">\n <pre>\n {\"\\n\"}\n <code className=\"language-javascript\">{\"// js code\"}</code>\n </pre>\n <pre>\n {\"\\n\"}\n <code className=\"language-python\">{\"# py code\"}</code>\n </pre>\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"language-selector\")).toBeTruthy();\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\"// js code\");\n });\n });\n\n describe(\"JSON-only snippets\", () => {\n it(\"always shows JSON content regardless of selected language\", () => {\n render(\n <CodeSnippet lang=\"ruby\">\n {makeSnippet(\"json\", '{\"key\": \"value\"}')}\n </CodeSnippet>,\n );\n expect(screen.getByTestId(\"code-block\").textContent).toBe(\n '{\"key\": \"value\"}',\n );\n });\n });\n\n describe(\"language ordering\", () => {\n it(\"respects custom language ordering\", () => {\n render(\n <CodeSnippet\n lang=\"javascript\"\n languageOrdering={[\"python\", \"typescript\", \"javascript\"]}\n >\n {makeSnippet(\"javascript\", \"// js\")}\n {makeSnippet(\"typescript\", \"// ts\")}\n {makeSnippet(\"python\", \"# py\")}\n </CodeSnippet>,\n );\n const selector = screen.getByTestId(\"language-selector\");\n const buttons = within(selector).getAllByRole(\"button\");\n expect(buttons[0].textContent).toBe(\"python\");\n expect(buttons[1].textContent).toBe(\"typescript\");\n expect(buttons[2].textContent).toBe(\"javascript\");\n });\n });\n});\n"],"names":["React","describe","expect","it","vi","afterEach","render","screen","within","cleanup","CodeSnippet","mock","default","snippet","language","div","data-testid","data-language","name","span","data-icon","children","onClick","active","button","data-active","languages","activeLanguage","onLanguageChange","map","lang","key","content","makeSnippet","pre","code","className","getByTestId","textContent","toBe","container","labelSpans","querySelectorAll","labels","Array","from","el","toContain","toBeTruthy","sdk","toggles","getAllByTestId","toHaveLength","fixed","queryAllByTestId","queryByTestId","toBeNull","headerRow","title","getByText","onChange","fn","pyButton","click","toHaveBeenCalledWith","undefined","languageOrdering","selector","buttons","getAllByRole"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import React,{memo}from"react";import Icon from"../Icon";import TooltipButton from"./TooltipButton";const CopyButton=memo(({onCopy,isCopied,tooltip="Copy"})=>{return React.createElement("div",{className:"absolute top-2 right-2 z-10"},React.createElement(TooltipButton,{tooltip:tooltip,onClick:onCopy,variant:"icon-button"},React.createElement(Icon,{name:"icon-gui-document-duplicate-outline",size:"20px",color:"text-neutral-1300 dark:text-neutral-000"})),isCopied?React.createElement("div",{className:"absolute right-10 top-0 bg-neutral-1300 dark:bg-neutral-000 text-neutral-000 dark:text-neutral-1300 py-1.5 px-3 rounded ui-text-label4 whitespace-nowrap"},"Copied!"):null)});CopyButton.displayName="CopyButton";export default CopyButton;
1
+ import React,{useState}from"react";import Icon from"../Icon";import TooltipButton from"./TooltipButton";const CopyButton=({onCopy,tooltip="Copy"})=>{const[isCopied,setIsCopied]=useState(false);const[isHovering,setIsHovering]=useState(false);return React.createElement("div",{className:"absolute top-2 right-2 z-10 rounded-lg focus-base",role:"button",tabIndex:0,onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>{setIsHovering(false);setTimeout(()=>{setIsCopied(false)},250)}},React.createElement(TooltipButton,{tooltip:isCopied?"Copied!":tooltip,onClick:()=>{onCopy();setIsCopied(true)},tooltipRootProps:{open:isHovering},variant:"icon-button"},React.createElement(Icon,{name:"icon-gui-document-duplicate-outline",size:"20px",color:"text-neutral-1300 dark:text-neutral-000"})))};export default CopyButton;
2
2
  //# sourceMappingURL=CopyButton.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/CopyButton.tsx"],"sourcesContent":["import React, { memo } from \"react\";\nimport Icon from \"../Icon\";\nimport TooltipButton from \"./TooltipButton\";\n\ntype CopyButtonProps = {\n onCopy: () => void;\n isCopied: boolean;\n tooltip?: string;\n};\n\n/**\n * A reusable copy button component with tooltip and copied indicator\n */\nconst CopyButton = memo(\n ({ onCopy, isCopied, tooltip = \"Copy\" }: CopyButtonProps) => {\n return (\n <div className=\"absolute top-2 right-2 z-10\">\n <TooltipButton tooltip={tooltip} onClick={onCopy} variant=\"icon-button\">\n <Icon\n name=\"icon-gui-document-duplicate-outline\"\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </TooltipButton>\n\n {isCopied ? (\n <div className=\"absolute right-10 top-0 bg-neutral-1300 dark:bg-neutral-000 text-neutral-000 dark:text-neutral-1300 py-1.5 px-3 rounded ui-text-label4 whitespace-nowrap\">\n Copied!\n </div>\n ) : null}\n </div>\n );\n },\n);\n\n// Add displayName for better debugging\nCopyButton.displayName = \"CopyButton\";\n\nexport default CopyButton;\n"],"names":["React","memo","Icon","TooltipButton","CopyButton","onCopy","isCopied","tooltip","div","className","onClick","variant","name","size","color","displayName"],"mappings":"AAAA,OAAOA,OAASC,IAAI,KAAQ,OAAQ,AACpC,QAAOC,SAAU,SAAU,AAC3B,QAAOC,kBAAmB,iBAAkB,CAW5C,MAAMC,WAAaH,KACjB,CAAC,CAAEI,MAAM,CAAEC,QAAQ,CAAEC,QAAU,MAAM,CAAmB,IACtD,OACE,oBAACC,OAAIC,UAAU,+BACb,oBAACN,eAAcI,QAASA,QAASG,QAASL,OAAQM,QAAQ,eACxD,oBAACT,MACCU,KAAK,sCACLC,KAAK,OACLC,MAAM,6CAITR,SACC,oBAACE,OAAIC,UAAU,4JAA2J,WAGxK,KAGV,EAIFL,CAAAA,WAAWW,WAAW,CAAG,YAEzB,gBAAeX,UAAW"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/CopyButton.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport Icon from \"../Icon\";\nimport TooltipButton from \"./TooltipButton\";\n\ntype CopyButtonProps = {\n onCopy: () => void;\n tooltip?: string;\n};\n\nconst CopyButton = ({ onCopy, tooltip = \"Copy\" }: CopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const [isHovering, setIsHovering] = useState(false);\n\n return (\n <div\n className=\"absolute top-2 right-2 z-10 rounded-lg focus-base\"\n role=\"button\"\n tabIndex={0}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => {\n setIsHovering(false);\n\n setTimeout(() => {\n setIsCopied(false);\n }, 250);\n }}\n >\n <TooltipButton\n tooltip={isCopied ? \"Copied!\" : tooltip}\n onClick={() => {\n onCopy();\n setIsCopied(true);\n }}\n tooltipRootProps={{\n open: isHovering,\n }}\n variant=\"icon-button\"\n >\n <Icon\n name=\"icon-gui-document-duplicate-outline\"\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </TooltipButton>\n </div>\n );\n};\n\nexport default CopyButton;\n"],"names":["React","useState","Icon","TooltipButton","CopyButton","onCopy","tooltip","isCopied","setIsCopied","isHovering","setIsHovering","div","className","role","tabIndex","onMouseEnter","onMouseLeave","setTimeout","onClick","tooltipRootProps","open","variant","name","size","color"],"mappings":"AAAA,OAAOA,OAASC,QAAQ,KAAQ,OAAQ,AACxC,QAAOC,SAAU,SAAU,AAC3B,QAAOC,kBAAmB,iBAAkB,CAO5C,MAAMC,WAAa,CAAC,CAAEC,MAAM,CAAEC,QAAU,MAAM,CAAmB,IAC/D,KAAM,CAACC,SAAUC,YAAY,CAAGP,SAAS,OACzC,KAAM,CAACQ,WAAYC,cAAc,CAAGT,SAAS,OAE7C,OACE,oBAACU,OACCC,UAAU,oDACVC,KAAK,SACLC,SAAU,EACVC,aAAc,IAAML,cAAc,MAClCM,aAAc,KACZN,cAAc,OAEdO,WAAW,KACTT,YAAY,MACd,EAAG,IACL,GAEA,oBAACL,eACCG,QAASC,SAAW,UAAYD,QAChCY,QAAS,KACPb,SACAG,YAAY,KACd,EACAW,iBAAkB,CAChBC,KAAMX,UACR,EACAY,QAAQ,eAER,oBAACnB,MACCoB,KAAK,sCACLC,KAAK,OACLC,MAAM,6CAKhB,CAEA,gBAAepB,UAAW"}
@@ -1,2 +1,2 @@
1
- import React,{memo,useMemo}from"react";import*as Select from"@radix-ui/react-select";import Icon from"../Icon";import TooltipButton from"./TooltipButton";import{getLanguageInfo}from"./languages";const LanguageSelector=memo(({languages,activeLanguage,onLanguageChange})=>{const desktopLanguageElements=useMemo(()=>languages.map(lang=>{const active=activeLanguage===lang;const displayName=getLanguageInfo(lang).label;return React.createElement(TooltipButton,{key:lang,tooltip:displayName,active:active,onClick:()=>onLanguageChange(lang),icon:getLanguageInfo(lang).icon,variant:"segmented",size:"sm"},displayName)}),[languages,activeLanguage,onLanguageChange]);const mobileLanguageElements=useMemo(()=>languages.map(lang=>React.createElement(Select.Item,{key:lang,value:lang,className:"relative flex items-center rounded px-2 py-1.5 text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base"},React.createElement(Select.ItemText,{asChild:true},React.createElement("div",{className:"flex items-center gap-2"},React.createElement(Icon,{name:getLanguageInfo(lang).icon,size:"20px"}),React.createElement("span",null,getLanguageInfo(lang).label))),React.createElement(Select.ItemIndicator,{className:"absolute right-2"},React.createElement(Icon,{name:"icon-gui-check-outline",size:"16px"})))),[languages]);const mobileSelectValue=useMemo(()=>activeLanguage?React.createElement("div",{className:"flex items-center gap-2"},React.createElement(Icon,{name:getLanguageInfo(activeLanguage).icon,size:"20px"}),React.createElement("span",null,getLanguageInfo(activeLanguage).label)):null,[activeLanguage]);return React.createElement("div",{className:"p-2 border-b border-neutral-200 dark:border-neutral-1100 overflow-x-auto h-[3.625rem]"},React.createElement("div",{className:"hidden sm:flex gap-2"},desktopLanguageElements),React.createElement("div",{className:"sm:hidden w-full"},React.createElement(Select.Root,{value:activeLanguage||undefined,onValueChange:onLanguageChange},React.createElement(Select.Trigger,{className:"w-full inline-flex items-center justify-between rounded-lg px-3 py-2 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-1 border border-neutral-300 dark:border-neutral-900 focus-base","aria-label":"Select language"},React.createElement(Select.Value,{asChild:true},mobileSelectValue),React.createElement(Select.Icon,null,React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px"}))),React.createElement(Select.Portal,null,React.createElement(Select.Content,{className:"overflow-hidden rounded-md bg-neutral-000 dark:bg-neutral-1300 border border-neutral-200 dark:border-neutral-1000 shadow-md z-50 w-[var(--radix-select-trigger-width)]",position:"popper"},React.createElement(Select.ScrollUpButton,{className:"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base"},React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px",additionalCSS:"rotate-180"})),React.createElement(Select.Viewport,{className:"p-1"},mobileLanguageElements),React.createElement(Select.ScrollDownButton,{className:"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base"},React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px"})))))))});LanguageSelector.displayName="LanguageSelector";export default LanguageSelector;
1
+ import React,{useMemo}from"react";import*as Select from"@radix-ui/react-select";import Icon from"../Icon";import TooltipButton from"./TooltipButton";import{getLanguageInfo}from"./languages";const LanguageSelector=({languages,activeLanguage,onLanguageChange})=>{const desktopLanguageElements=useMemo(()=>languages.map(lang=>{const active=activeLanguage===lang;const displayName=getLanguageInfo(lang).label;return React.createElement(TooltipButton,{key:lang,tooltip:displayName,active:active,onClick:()=>onLanguageChange(lang),icon:getLanguageInfo(lang).icon,variant:"segmented",size:"xs"},displayName)}),[languages,activeLanguage,onLanguageChange]);const mobileLanguageElements=useMemo(()=>languages.map(lang=>React.createElement(Select.Item,{key:lang,value:lang,className:"relative flex items-center rounded px-2 py-1.5 text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base"},React.createElement(Select.ItemText,{asChild:true},React.createElement("div",{className:"flex items-center gap-2"},React.createElement(Icon,{name:getLanguageInfo(lang).icon,size:"20px"}),React.createElement("span",null,getLanguageInfo(lang).label))),React.createElement(Select.ItemIndicator,{className:"absolute right-2"},React.createElement(Icon,{name:"icon-gui-check-outline",size:"16px"})))),[languages]);const mobileSelectValue=useMemo(()=>activeLanguage?React.createElement("div",{className:"flex items-center gap-2"},React.createElement(Icon,{name:getLanguageInfo(activeLanguage).icon,size:"20px"}),React.createElement("span",null,getLanguageInfo(activeLanguage).label)):null,[activeLanguage]);return React.createElement("div",{className:"p-2 border-b border-neutral-300 dark:border-neutral-1000 overflow-x-auto"},React.createElement("div",{className:"hidden sm:flex gap-1"},desktopLanguageElements),React.createElement("div",{className:"sm:hidden w-full"},React.createElement(Select.Root,{value:activeLanguage||undefined,onValueChange:onLanguageChange},React.createElement(Select.Trigger,{className:"w-full inline-flex items-center justify-between rounded-lg px-3 py-2 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-1 border border-neutral-300 dark:border-neutral-900 focus-base","aria-label":"Select language"},React.createElement(Select.Value,{asChild:true},mobileSelectValue),React.createElement(Select.Icon,null,React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px"}))),React.createElement(Select.Portal,null,React.createElement(Select.Content,{className:"overflow-hidden rounded-md bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 shadow-md z-50 w-[var(--radix-select-trigger-width)]",position:"popper"},React.createElement(Select.ScrollUpButton,{className:"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base"},React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px",additionalCSS:"rotate-180"})),React.createElement(Select.Viewport,{className:"p-1"},mobileLanguageElements),React.createElement(Select.ScrollDownButton,{className:"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base"},React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px"})))))))};export default LanguageSelector;
2
2
  //# sourceMappingURL=LanguageSelector.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/LanguageSelector.tsx"],"sourcesContent":["import React, { memo, useMemo } from \"react\";\nimport * as Select from \"@radix-ui/react-select\";\nimport Icon from \"../Icon\";\nimport TooltipButton from \"./TooltipButton\";\nimport { getLanguageInfo } from \"./languages\";\n\ntype LanguageSelectorProps = {\n languages: string[];\n activeLanguage: string;\n onLanguageChange: (language: string) => void;\n};\n\nconst LanguageSelector = memo(\n ({ languages, activeLanguage, onLanguageChange }: LanguageSelectorProps) => {\n const desktopLanguageElements = useMemo(\n () =>\n languages.map((lang) => {\n const active = activeLanguage === lang;\n const displayName = getLanguageInfo(lang).label;\n\n return (\n <TooltipButton\n key={lang}\n tooltip={displayName}\n active={active}\n onClick={() => onLanguageChange(lang)}\n icon={getLanguageInfo(lang).icon}\n variant=\"segmented\"\n size=\"sm\"\n >\n {displayName}\n </TooltipButton>\n );\n }),\n [languages, activeLanguage, onLanguageChange],\n );\n\n const mobileLanguageElements = useMemo(\n () =>\n languages.map((lang) => (\n <Select.Item\n key={lang}\n value={lang}\n className=\"relative flex items-center rounded px-2 py-1.5 text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base\"\n >\n <Select.ItemText asChild>\n <div className=\"flex items-center gap-2\">\n <Icon name={getLanguageInfo(lang).icon} size=\"20px\" />\n <span>{getLanguageInfo(lang).label}</span>\n </div>\n </Select.ItemText>\n <Select.ItemIndicator className=\"absolute right-2\">\n <Icon name=\"icon-gui-check-outline\" size=\"16px\" />\n </Select.ItemIndicator>\n </Select.Item>\n )),\n [languages],\n );\n\n const mobileSelectValue = useMemo(\n () =>\n activeLanguage ? (\n <div className=\"flex items-center gap-2\">\n <Icon name={getLanguageInfo(activeLanguage).icon} size=\"20px\" />\n <span>{getLanguageInfo(activeLanguage).label}</span>\n </div>\n ) : null,\n [activeLanguage],\n );\n\n return (\n <div className=\"p-2 border-b border-neutral-200 dark:border-neutral-1100 overflow-x-auto h-[3.625rem]\">\n <div className=\"hidden sm:flex gap-2\">{desktopLanguageElements}</div>\n\n <div className=\"sm:hidden w-full\">\n <Select.Root\n value={activeLanguage || undefined}\n onValueChange={onLanguageChange}\n >\n <Select.Trigger\n className=\"w-full inline-flex items-center justify-between rounded-lg px-3 py-2 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-1 border border-neutral-300 dark:border-neutral-900 focus-base\"\n aria-label=\"Select language\"\n >\n <Select.Value asChild>{mobileSelectValue}</Select.Value>\n <Select.Icon>\n <Icon name=\"icon-gui-chevron-down-outline\" size=\"16px\" />\n </Select.Icon>\n </Select.Trigger>\n\n <Select.Portal>\n <Select.Content\n className=\"overflow-hidden rounded-md bg-neutral-000 dark:bg-neutral-1300 border border-neutral-200 dark:border-neutral-1000 shadow-md z-50 w-[var(--radix-select-trigger-width)]\"\n position=\"popper\"\n >\n <Select.ScrollUpButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon\n name=\"icon-gui-chevron-down-outline\"\n size=\"16px\"\n additionalCSS=\"rotate-180\"\n />\n </Select.ScrollUpButton>\n\n <Select.Viewport className=\"p-1\">\n {mobileLanguageElements}\n </Select.Viewport>\n\n <Select.ScrollDownButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon name=\"icon-gui-chevron-down-outline\" size=\"16px\" />\n </Select.ScrollDownButton>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </div>\n </div>\n );\n },\n);\n\n// Define a display name to improve debugging\nLanguageSelector.displayName = \"LanguageSelector\";\n\nexport default LanguageSelector;\n"],"names":["React","memo","useMemo","Select","Icon","TooltipButton","getLanguageInfo","LanguageSelector","languages","activeLanguage","onLanguageChange","desktopLanguageElements","map","lang","active","displayName","label","key","tooltip","onClick","icon","variant","size","mobileLanguageElements","Item","value","className","ItemText","asChild","div","name","span","ItemIndicator","mobileSelectValue","Root","undefined","onValueChange","Trigger","aria-label","Value","Portal","Content","position","ScrollUpButton","additionalCSS","Viewport","ScrollDownButton"],"mappings":"AAAA,OAAOA,OAASC,IAAI,CAAEC,OAAO,KAAQ,OAAQ,AAC7C,WAAYC,WAAY,wBAAyB,AACjD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,kBAAmB,iBAAkB,AAC5C,QAASC,eAAe,KAAQ,aAAc,CAQ9C,MAAMC,iBAAmBN,KACvB,CAAC,CAAEO,SAAS,CAAEC,cAAc,CAAEC,gBAAgB,CAAyB,IACrE,MAAMC,wBAA0BT,QAC9B,IACEM,UAAUI,GAAG,CAAC,AAACC,OACb,MAAMC,OAASL,iBAAmBI,KAClC,MAAME,YAAcT,gBAAgBO,MAAMG,KAAK,CAE/C,OACE,oBAACX,eACCY,IAAKJ,KACLK,QAASH,YACTD,OAAQA,OACRK,QAAS,IAAMT,iBAAiBG,MAChCO,KAAMd,gBAAgBO,MAAMO,IAAI,CAChCC,QAAQ,YACRC,KAAK,MAEJP,YAGP,GACF,CAACP,UAAWC,eAAgBC,iBAAiB,EAG/C,MAAMa,uBAAyBrB,QAC7B,IACEM,UAAUI,GAAG,CAAC,AAACC,MACb,oBAACV,OAAOqB,IAAI,EACVP,IAAKJ,KACLY,MAAOZ,KACPa,UAAU,mRAEV,oBAACvB,OAAOwB,QAAQ,EAACC,QAAAA,MACf,oBAACC,OAAIH,UAAU,2BACb,oBAACtB,MAAK0B,KAAMxB,gBAAgBO,MAAMO,IAAI,CAAEE,KAAK,SAC7C,oBAACS,YAAMzB,gBAAgBO,MAAMG,KAAK,IAGtC,oBAACb,OAAO6B,aAAa,EAACN,UAAU,oBAC9B,oBAACtB,MAAK0B,KAAK,yBAAyBR,KAAK,YAIjD,CAACd,UAAU,EAGb,MAAMyB,kBAAoB/B,QACxB,IACEO,eACE,oBAACoB,OAAIH,UAAU,2BACb,oBAACtB,MAAK0B,KAAMxB,gBAAgBG,gBAAgBW,IAAI,CAAEE,KAAK,SACvD,oBAACS,YAAMzB,gBAAgBG,gBAAgBO,KAAK,GAE5C,KACN,CAACP,eAAe,EAGlB,OACE,oBAACoB,OAAIH,UAAU,yFACb,oBAACG,OAAIH,UAAU,wBAAwBf,yBAEvC,oBAACkB,OAAIH,UAAU,oBACb,oBAACvB,OAAO+B,IAAI,EACVT,MAAOhB,gBAAkB0B,UACzBC,cAAe1B,kBAEf,oBAACP,OAAOkC,OAAO,EACbX,UAAU,8QACVY,aAAW,mBAEX,oBAACnC,OAAOoC,KAAK,EAACX,QAAAA,MAASK,mBACvB,oBAAC9B,OAAOC,IAAI,MACV,oBAACA,MAAK0B,KAAK,gCAAgCR,KAAK,WAIpD,oBAACnB,OAAOqC,MAAM,MACZ,oBAACrC,OAAOsC,OAAO,EACbf,UAAU,yKACVgB,SAAS,UAET,oBAACvC,OAAOwC,cAAc,EAACjB,UAAU,8IAC/B,oBAACtB,MACC0B,KAAK,gCACLR,KAAK,OACLsB,cAAc,gBAIlB,oBAACzC,OAAO0C,QAAQ,EAACnB,UAAU,OACxBH,wBAGH,oBAACpB,OAAO2C,gBAAgB,EAACpB,UAAU,8IACjC,oBAACtB,MAAK0B,KAAK,gCAAgCR,KAAK,cAQhE,EAIFf,CAAAA,iBAAiBQ,WAAW,CAAG,kBAE/B,gBAAeR,gBAAiB"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/LanguageSelector.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport * as Select from \"@radix-ui/react-select\";\nimport Icon from \"../Icon\";\nimport TooltipButton from \"./TooltipButton\";\nimport { getLanguageInfo } from \"./languages\";\n\ntype LanguageSelectorProps = {\n languages: string[];\n activeLanguage: string;\n onLanguageChange: (language: string) => void;\n};\n\nconst LanguageSelector = ({\n languages,\n activeLanguage,\n onLanguageChange,\n}: LanguageSelectorProps) => {\n const desktopLanguageElements = useMemo(\n () =>\n languages.map((lang) => {\n const active = activeLanguage === lang;\n const displayName = getLanguageInfo(lang).label;\n\n return (\n <TooltipButton\n key={lang}\n tooltip={displayName}\n active={active}\n onClick={() => onLanguageChange(lang)}\n icon={getLanguageInfo(lang).icon}\n variant=\"segmented\"\n size=\"xs\"\n >\n {displayName}\n </TooltipButton>\n );\n }),\n [languages, activeLanguage, onLanguageChange],\n );\n\n const mobileLanguageElements = useMemo(\n () =>\n languages.map((lang) => (\n <Select.Item\n key={lang}\n value={lang}\n className=\"relative flex items-center rounded px-2 py-1.5 text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base\"\n >\n <Select.ItemText asChild>\n <div className=\"flex items-center gap-2\">\n <Icon name={getLanguageInfo(lang).icon} size=\"20px\" />\n <span>{getLanguageInfo(lang).label}</span>\n </div>\n </Select.ItemText>\n <Select.ItemIndicator className=\"absolute right-2\">\n <Icon name=\"icon-gui-check-outline\" size=\"16px\" />\n </Select.ItemIndicator>\n </Select.Item>\n )),\n [languages],\n );\n\n const mobileSelectValue = useMemo(\n () =>\n activeLanguage ? (\n <div className=\"flex items-center gap-2\">\n <Icon name={getLanguageInfo(activeLanguage).icon} size=\"20px\" />\n <span>{getLanguageInfo(activeLanguage).label}</span>\n </div>\n ) : null,\n [activeLanguage],\n );\n\n return (\n <div className=\"p-2 border-b border-neutral-300 dark:border-neutral-1000 overflow-x-auto\">\n <div className=\"hidden sm:flex gap-1\">{desktopLanguageElements}</div>\n\n <div className=\"sm:hidden w-full\">\n <Select.Root\n value={activeLanguage || undefined}\n onValueChange={onLanguageChange}\n >\n <Select.Trigger\n className=\"w-full inline-flex items-center justify-between rounded-lg px-3 py-2 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-1 border border-neutral-300 dark:border-neutral-900 focus-base\"\n aria-label=\"Select language\"\n >\n <Select.Value asChild>{mobileSelectValue}</Select.Value>\n <Select.Icon>\n <Icon name=\"icon-gui-chevron-down-outline\" size=\"16px\" />\n </Select.Icon>\n </Select.Trigger>\n\n <Select.Portal>\n <Select.Content\n className=\"overflow-hidden rounded-md bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 shadow-md z-50 w-[var(--radix-select-trigger-width)]\"\n position=\"popper\"\n >\n <Select.ScrollUpButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon\n name=\"icon-gui-chevron-down-outline\"\n size=\"16px\"\n additionalCSS=\"rotate-180\"\n />\n </Select.ScrollUpButton>\n\n <Select.Viewport className=\"p-1\">\n {mobileLanguageElements}\n </Select.Viewport>\n\n <Select.ScrollDownButton className=\"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base\">\n <Icon name=\"icon-gui-chevron-down-outline\" size=\"16px\" />\n </Select.ScrollDownButton>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </div>\n </div>\n );\n};\n\nexport default LanguageSelector;\n"],"names":["React","useMemo","Select","Icon","TooltipButton","getLanguageInfo","LanguageSelector","languages","activeLanguage","onLanguageChange","desktopLanguageElements","map","lang","active","displayName","label","key","tooltip","onClick","icon","variant","size","mobileLanguageElements","Item","value","className","ItemText","asChild","div","name","span","ItemIndicator","mobileSelectValue","Root","undefined","onValueChange","Trigger","aria-label","Value","Portal","Content","position","ScrollUpButton","additionalCSS","Viewport","ScrollDownButton"],"mappings":"AAAA,OAAOA,OAASC,OAAO,KAAQ,OAAQ,AACvC,WAAYC,WAAY,wBAAyB,AACjD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,kBAAmB,iBAAkB,AAC5C,QAASC,eAAe,KAAQ,aAAc,CAQ9C,MAAMC,iBAAmB,CAAC,CACxBC,SAAS,CACTC,cAAc,CACdC,gBAAgB,CACM,IACtB,MAAMC,wBAA0BT,QAC9B,IACEM,UAAUI,GAAG,CAAC,AAACC,OACb,MAAMC,OAASL,iBAAmBI,KAClC,MAAME,YAAcT,gBAAgBO,MAAMG,KAAK,CAE/C,OACE,oBAACX,eACCY,IAAKJ,KACLK,QAASH,YACTD,OAAQA,OACRK,QAAS,IAAMT,iBAAiBG,MAChCO,KAAMd,gBAAgBO,MAAMO,IAAI,CAChCC,QAAQ,YACRC,KAAK,MAEJP,YAGP,GACF,CAACP,UAAWC,eAAgBC,iBAAiB,EAG/C,MAAMa,uBAAyBrB,QAC7B,IACEM,UAAUI,GAAG,CAAC,AAACC,MACb,oBAACV,OAAOqB,IAAI,EACVP,IAAKJ,KACLY,MAAOZ,KACPa,UAAU,mRAEV,oBAACvB,OAAOwB,QAAQ,EAACC,QAAAA,MACf,oBAACC,OAAIH,UAAU,2BACb,oBAACtB,MAAK0B,KAAMxB,gBAAgBO,MAAMO,IAAI,CAAEE,KAAK,SAC7C,oBAACS,YAAMzB,gBAAgBO,MAAMG,KAAK,IAGtC,oBAACb,OAAO6B,aAAa,EAACN,UAAU,oBAC9B,oBAACtB,MAAK0B,KAAK,yBAAyBR,KAAK,YAIjD,CAACd,UAAU,EAGb,MAAMyB,kBAAoB/B,QACxB,IACEO,eACE,oBAACoB,OAAIH,UAAU,2BACb,oBAACtB,MAAK0B,KAAMxB,gBAAgBG,gBAAgBW,IAAI,CAAEE,KAAK,SACvD,oBAACS,YAAMzB,gBAAgBG,gBAAgBO,KAAK,GAE5C,KACN,CAACP,eAAe,EAGlB,OACE,oBAACoB,OAAIH,UAAU,4EACb,oBAACG,OAAIH,UAAU,wBAAwBf,yBAEvC,oBAACkB,OAAIH,UAAU,oBACb,oBAACvB,OAAO+B,IAAI,EACVT,MAAOhB,gBAAkB0B,UACzBC,cAAe1B,kBAEf,oBAACP,OAAOkC,OAAO,EACbX,UAAU,8QACVY,aAAW,mBAEX,oBAACnC,OAAOoC,KAAK,EAACX,QAAAA,MAASK,mBACvB,oBAAC9B,OAAOC,IAAI,MACV,oBAACA,MAAK0B,KAAK,gCAAgCR,KAAK,WAIpD,oBAACnB,OAAOqC,MAAM,MACZ,oBAACrC,OAAOsC,OAAO,EACbf,UAAU,yKACVgB,SAAS,UAET,oBAACvC,OAAOwC,cAAc,EAACjB,UAAU,8IAC/B,oBAACtB,MACC0B,KAAK,gCACLR,KAAK,OACLsB,cAAc,gBAIlB,oBAACzC,OAAO0C,QAAQ,EAACnB,UAAU,OACxBH,wBAGH,oBAACpB,OAAO2C,gBAAgB,EAACpB,UAAU,8IACjC,oBAACtB,MAAK0B,KAAK,gCAAgCR,KAAK,cAQhE,CAEA,gBAAef,gBAAiB"}
@@ -1,2 +1,2 @@
1
- import React,{useRef,useState,useCallback,memo}from"react";import Icon from"../Icon";import Code from"../Code";import cn from"../utils/cn";import useCopyToClipboard from"../utils/useCopyToClipboard";import CopyButton from"./CopyButton";const PlainCodeView=({content,className,language,icon})=>{const{isCopied,copy}=useCopyToClipboard();const codeRef=useRef(null);const[isHovering,setIsHovering]=useState(false);const handleCopy=useCallback(()=>{copy(content)},[copy,content]);return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative flex items-center",language==="shell"?"min-h-[3.375rem]":"min-h-12",className),onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0,ref:codeRef},icon&&React.createElement("div",{className:"absolute top-2 left-2 z-10"},React.createElement("div",{className:"w-9 h-9 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100"},React.createElement(Icon,{name:icon,size:"20px",color:"text-neutral-1300 dark:text-neutral-000"}))),React.createElement(Code,{language:language,snippet:content,additionalCSS:cn("w-full bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 px-4 py-2",icon&&"pl-14"),showLines:false}),isHovering&&React.createElement(CopyButton,{onCopy:handleCopy,isCopied:isCopied}))};PlainCodeView.displayName="PlainCodeView";export default memo(PlainCodeView);
1
+ import React,{useRef,useState}from"react";import Icon from"../Icon";import Code from"../Code";import cn from"../utils/cn";import CopyButton from"./CopyButton";const PlainCodeView=({content,className,language,icon})=>{const codeRef=useRef(null);const[isHovering,setIsHovering]=useState(false);return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative flex items-center",language==="shell"?"min-h-[3.375rem]":"min-h-12",className),onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0,role:"button","aria-label":"Focusable code view area",ref:codeRef},icon&&React.createElement("div",{className:"absolute top-2 left-2 z-10"},React.createElement("div",{className:"w-9 h-9 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100"},React.createElement(Icon,{name:icon,size:"20px",color:"text-neutral-1300 dark:text-neutral-000"}))),React.createElement(Code,{language:language,snippet:content,additionalCSS:cn("w-full bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 px-4 py-2",icon&&"pl-14"),showLines:false}),isHovering&&React.createElement(CopyButton,{onCopy:()=>navigator.clipboard.writeText(content)}))};export default PlainCodeView;
2
2
  //# sourceMappingURL=PlainCodeView.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/PlainCodeView.tsx"],"sourcesContent":["import React, { useRef, useState, useCallback, memo } from \"react\";\nimport Icon from \"../Icon\";\nimport Code from \"../Code\";\nimport cn from \"../utils/cn\";\nimport useCopyToClipboard from \"../utils/useCopyToClipboard\";\nimport CopyButton from \"./CopyButton\";\nimport { IconName } from \"../Icon/types\";\n\ntype PlainCodeViewProps = {\n content: string;\n language: string;\n icon: IconName | null;\n className?: string;\n};\n\n/**\n * A specialized component for displaying plain code (shell commands, text, etc.) with copy functionality\n */\nconst PlainCodeView: React.FC<PlainCodeViewProps> = ({\n content,\n className,\n language,\n icon,\n}) => {\n const { isCopied, copy } = useCopyToClipboard();\n const codeRef = useRef<HTMLDivElement>(null);\n const [isHovering, setIsHovering] = useState(false);\n\n // Handler to copy the content\n const handleCopy = useCallback(() => {\n copy(content);\n }, [copy, content]);\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative flex items-center\",\n language === \"shell\" ? \"min-h-[3.375rem]\" : \"min-h-12\",\n className,\n )}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n tabIndex={0}\n ref={codeRef}\n >\n {icon && (\n <div className=\"absolute top-2 left-2 z-10\">\n <div className=\"w-9 h-9 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100\">\n <Icon\n name={icon}\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </div>\n </div>\n )}\n\n <Code\n language={language}\n snippet={content}\n additionalCSS={cn(\n \"w-full bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 px-4 py-2\",\n icon && \"pl-14\",\n )}\n showLines={false}\n />\n\n {isHovering && <CopyButton onCopy={handleCopy} isCopied={isCopied} />}\n </div>\n );\n};\n\nPlainCodeView.displayName = \"PlainCodeView\";\n\nexport default memo(PlainCodeView);\n"],"names":["React","useRef","useState","useCallback","memo","Icon","Code","cn","useCopyToClipboard","CopyButton","PlainCodeView","content","className","language","icon","isCopied","copy","codeRef","isHovering","setIsHovering","handleCopy","div","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","ref","name","size","color","snippet","additionalCSS","showLines","onCopy","displayName"],"mappings":"AAAA,OAAOA,OAASC,MAAM,CAAEC,QAAQ,CAAEC,WAAW,CAAEC,IAAI,KAAQ,OAAQ,AACnE,QAAOC,SAAU,SAAU,AAC3B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,uBAAwB,6BAA8B,AAC7D,QAAOC,eAAgB,cAAe,CAatC,MAAMC,cAA8C,CAAC,CACnDC,OAAO,CACPC,SAAS,CACTC,QAAQ,CACRC,IAAI,CACL,IACC,KAAM,CAAEC,QAAQ,CAAEC,IAAI,CAAE,CAAGR,qBAC3B,MAAMS,QAAUhB,OAAuB,MACvC,KAAM,CAACiB,WAAYC,cAAc,CAAGjB,SAAS,OAG7C,MAAMkB,WAAajB,YAAY,KAC7Ba,KAAKL,QACP,EAAG,CAACK,KAAML,QAAQ,EAElB,OACE,oBAACU,OACCT,UAAWL,GACT,+IACAM,WAAa,QAAU,mBAAqB,WAC5CD,WAEFU,aAAc,IAAMH,cAAc,MAClCI,aAAc,IAAMJ,cAAc,OAClCK,QAAS,IAAML,cAAc,MAC7BM,OAAQ,IAAMN,cAAc,OAC5BO,SAAU,EACVC,IAAKV,SAEJH,MACC,oBAACO,OAAIT,UAAU,8BACb,oBAACS,OAAIT,UAAU,2FACb,oBAACP,MACCuB,KAAMd,KACNe,KAAK,OACLC,MAAM,8CAMd,oBAACxB,MACCO,SAAUA,SACVkB,QAASpB,QACTqB,cAAezB,GACb,+FACAO,MAAQ,SAEVmB,UAAW,QAGZf,YAAc,oBAACT,YAAWyB,OAAQd,WAAYL,SAAUA,WAG/D,CAEAL,CAAAA,cAAcyB,WAAW,CAAG,eAE5B,gBAAe/B,KAAKM,cAAe"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/PlainCodeView.tsx"],"sourcesContent":["import React, { useRef, useState } from \"react\";\nimport Icon from \"../Icon\";\nimport Code from \"../Code\";\nimport cn from \"../utils/cn\";\nimport CopyButton from \"./CopyButton\";\nimport { IconName } from \"../Icon/types\";\n\ntype PlainCodeViewProps = {\n content: string;\n language: string;\n icon: IconName | null;\n className?: string;\n};\n\nconst PlainCodeView: React.FC<PlainCodeViewProps> = ({\n content,\n className,\n language,\n icon,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n const [isHovering, setIsHovering] = useState(false);\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative flex items-center\",\n language === \"shell\" ? \"min-h-[3.375rem]\" : \"min-h-12\",\n className,\n )}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n tabIndex={0}\n role=\"button\"\n aria-label=\"Focusable code view area\"\n ref={codeRef}\n >\n {icon && (\n <div className=\"absolute top-2 left-2 z-10\">\n <div className=\"w-9 h-9 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100\">\n <Icon\n name={icon}\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </div>\n </div>\n )}\n\n <Code\n language={language}\n snippet={content}\n additionalCSS={cn(\n \"w-full bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 px-4 py-2\",\n icon && \"pl-14\",\n )}\n showLines={false}\n />\n\n {isHovering && (\n <CopyButton onCopy={() => navigator.clipboard.writeText(content)} />\n )}\n </div>\n );\n};\n\nexport default PlainCodeView;\n"],"names":["React","useRef","useState","Icon","Code","cn","CopyButton","PlainCodeView","content","className","language","icon","codeRef","isHovering","setIsHovering","div","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","role","aria-label","ref","name","size","color","snippet","additionalCSS","showLines","onCopy","navigator","clipboard","writeText"],"mappings":"AAAA,OAAOA,OAASC,MAAM,CAAEC,QAAQ,KAAQ,OAAQ,AAChD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,eAAgB,cAAe,CAUtC,MAAMC,cAA8C,CAAC,CACnDC,OAAO,CACPC,SAAS,CACTC,QAAQ,CACRC,IAAI,CACL,IACC,MAAMC,QAAUX,OAAuB,MACvC,KAAM,CAACY,WAAYC,cAAc,CAAGZ,SAAS,OAE7C,OACE,oBAACa,OACCN,UAAWJ,GACT,+IACAK,WAAa,QAAU,mBAAqB,WAC5CD,WAEFO,aAAc,IAAMF,cAAc,MAClCG,aAAc,IAAMH,cAAc,OAClCI,QAAS,IAAMJ,cAAc,MAC7BK,OAAQ,IAAML,cAAc,OAC5BM,SAAU,EACVC,KAAK,SACLC,aAAW,2BACXC,IAAKX,SAEJD,MACC,oBAACI,OAAIN,UAAU,8BACb,oBAACM,OAAIN,UAAU,2FACb,oBAACN,MACCqB,KAAMb,KACNc,KAAK,OACLC,MAAM,8CAMd,oBAACtB,MACCM,SAAUA,SACViB,QAASnB,QACToB,cAAevB,GACb,+FACAM,MAAQ,SAEVkB,UAAW,QAGZhB,YACC,oBAACP,YAAWwB,OAAQ,IAAMC,UAAUC,SAAS,CAACC,SAAS,CAACzB,WAIhE,CAEA,gBAAeD,aAAc"}
@@ -1,2 +1,2 @@
1
- import React,{memo,useMemo}from"react";import Tooltip from"../Tooltip";import SegmentedControl from"../SegmentedControl";import cn from"../utils/cn";const TooltipButton=memo(({tooltip,active=false,onClick,icon,className,children,variant="segmented",size="sm",alwaysShowLabel=false})=>{const showTooltip=variant==="segmented"&&!active||variant==="icon-button";const showChildren=active||alwaysShowLabel;const buttonElement=useMemo(()=>{if(variant==="segmented"){return React.createElement(SegmentedControl,{size:size,active:active,onClick:onClick,leftIcon:icon,className:cn("focus-base",active?"bg-neutral-000 dark:bg-neutral-1300":"bg-neutral-100 dark:bg-neutral-1200",className)},showChildren?children:null)}return React.createElement("div",{role:"button",className:cn("w-8 h-8 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 transition-colors focus-base",className),onClick:onClick,"aria-label":tooltip},children)},[variant,size,active,onClick,icon,className,showChildren,children,tooltip]);if(showTooltip){return React.createElement(Tooltip,{triggerElement:buttonElement,className:"ml-0"},tooltip)}return buttonElement});TooltipButton.displayName="TooltipButton";export default TooltipButton;
1
+ import React,{useMemo}from"react";import Tooltip from"../Tooltip";import SegmentedControl from"../SegmentedControl";import cn from"../utils/cn";const TooltipButton=({tooltip,active=false,onClick,icon,className,children,variant="segmented",size="sm",alwaysShowLabel=false,tooltipRootProps})=>{const showTooltip=variant==="segmented"&&!active||variant==="icon-button";const showChildren=active||alwaysShowLabel;const buttonElement=useMemo(()=>{if(variant==="segmented"){return React.createElement(SegmentedControl,{size:size,active:active,onClick:onClick,leftIcon:icon,className:cn("focus-base transition-colors",active?"bg-neutral-000 dark:bg-neutral-1100":"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900",className)},showChildren?children:null)}return React.createElement("div",{role:"button",className:cn("w-8 h-8 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 transition-colors focus-base",className),onClick:onClick,onKeyDown:e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();onClick?.()}},tabIndex:0},children)},[variant,size,active,onClick,icon,className,showChildren,children]);if(showTooltip){return React.createElement(Tooltip,{triggerElement:buttonElement,rootProps:tooltipRootProps,className:"ml-0",contentProps:{className:"px-2 py-1 bg-neutral-1100 dark:bg-neutral-200 text-neutral-300 dark:text-neutral-1000"},triggerProps:{className:"ml-0 h-auto"}},tooltip)}return buttonElement};export default TooltipButton;
2
2
  //# sourceMappingURL=TooltipButton.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/TooltipButton.tsx"],"sourcesContent":["import React, { memo, useMemo } from \"react\";\nimport Tooltip from \"../Tooltip\";\nimport SegmentedControl from \"../SegmentedControl\";\nimport cn from \"../utils/cn\";\nimport { IconName } from \"../Icon/types\";\n\ntype TooltipButtonProps = {\n tooltip: string;\n active?: boolean;\n onClick: () => void;\n icon?: IconName;\n className?: string;\n children?: React.ReactNode;\n variant?: \"segmented\" | \"icon-button\";\n size?: \"sm\" | \"md\";\n alwaysShowLabel?: boolean;\n};\n\n/**\n * A unified tooltip button component that can render either a segmented control or an icon button\n */\nconst TooltipButton = memo(\n ({\n tooltip,\n active = false,\n onClick,\n icon,\n className,\n children,\n variant = \"segmented\",\n size = \"sm\",\n alwaysShowLabel = false,\n }: TooltipButtonProps) => {\n // Only show tooltip for inactive segmented controls or all icon buttons\n const showTooltip =\n (variant === \"segmented\" && !active) || variant === \"icon-button\";\n\n // Determine whether to show children based on active state and alwaysShowLabel\n const showChildren = active || alwaysShowLabel;\n\n // Create the button element based on variant\n const buttonElement = useMemo(() => {\n if (variant === \"segmented\") {\n return (\n <SegmentedControl\n size={size}\n active={active}\n onClick={onClick}\n leftIcon={icon}\n className={cn(\n \"focus-base\",\n active\n ? \"bg-neutral-000 dark:bg-neutral-1300\"\n : \"bg-neutral-100 dark:bg-neutral-1200\",\n className,\n )}\n >\n {showChildren ? children : null}\n </SegmentedControl>\n );\n }\n\n return (\n <div\n role=\"button\"\n className={cn(\n \"w-8 h-8 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 transition-colors focus-base\",\n className,\n )}\n onClick={onClick}\n aria-label={tooltip}\n >\n {children}\n </div>\n );\n }, [\n variant,\n size,\n active,\n onClick,\n icon,\n className,\n showChildren,\n children,\n tooltip,\n ]);\n\n // Render with tooltip if needed\n if (showTooltip) {\n return (\n <Tooltip triggerElement={buttonElement} className=\"ml-0\">\n {tooltip}\n </Tooltip>\n );\n }\n\n return buttonElement;\n },\n);\n\n// Add displayName for better debugging\nTooltipButton.displayName = \"TooltipButton\";\n\nexport default TooltipButton;\n"],"names":["React","memo","useMemo","Tooltip","SegmentedControl","cn","TooltipButton","tooltip","active","onClick","icon","className","children","variant","size","alwaysShowLabel","showTooltip","showChildren","buttonElement","leftIcon","div","role","aria-label","triggerElement","displayName"],"mappings":"AAAA,OAAOA,OAASC,IAAI,CAAEC,OAAO,KAAQ,OAAQ,AAC7C,QAAOC,YAAa,YAAa,AACjC,QAAOC,qBAAsB,qBAAsB,AACnD,QAAOC,OAAQ,aAAc,CAkB7B,MAAMC,cAAgBL,KACpB,CAAC,CACCM,OAAO,CACPC,OAAS,KAAK,CACdC,OAAO,CACPC,IAAI,CACJC,SAAS,CACTC,QAAQ,CACRC,QAAU,WAAW,CACrBC,KAAO,IAAI,CACXC,gBAAkB,KAAK,CACJ,IAEnB,MAAMC,YACJ,AAACH,UAAY,aAAe,CAACL,QAAWK,UAAY,cAGtD,MAAMI,aAAeT,QAAUO,gBAG/B,MAAMG,cAAgBhB,QAAQ,KAC5B,GAAIW,UAAY,YAAa,CAC3B,OACE,oBAACT,kBACCU,KAAMA,KACNN,OAAQA,OACRC,QAASA,QACTU,SAAUT,KACVC,UAAWN,GACT,aACAG,OACI,sCACA,sCACJG,YAGDM,aAAeL,SAAW,KAGjC,CAEA,OACE,oBAACQ,OACCC,KAAK,SACLV,UAAWN,GACT,uKACAM,WAEFF,QAASA,QACTa,aAAYf,SAEXK,SAGP,EAAG,CACDC,QACAC,KACAN,OACAC,QACAC,KACAC,UACAM,aACAL,SACAL,QACD,EAGD,GAAIS,YAAa,CACf,OACE,oBAACb,SAAQoB,eAAgBL,cAAeP,UAAU,QAC/CJ,QAGP,CAEA,OAAOW,aACT,EAIFZ,CAAAA,cAAckB,WAAW,CAAG,eAE5B,gBAAelB,aAAc"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/TooltipButton.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport Tooltip from \"../Tooltip\";\nimport SegmentedControl, { SegmentedControlSize } from \"../SegmentedControl\";\nimport cn from \"../utils/cn\";\nimport { IconName } from \"../Icon/types\";\nimport type { TooltipProps } from \"@radix-ui/react-tooltip\";\n\ntype TooltipButtonProps = {\n tooltip: string | React.ReactNode;\n active?: boolean;\n onClick: () => void;\n icon?: IconName;\n className?: string;\n children?: React.ReactNode;\n variant?: \"segmented\" | \"icon-button\";\n size?: SegmentedControlSize;\n alwaysShowLabel?: boolean;\n tooltipRootProps?: TooltipProps;\n};\n\nconst TooltipButton = ({\n tooltip,\n active = false,\n onClick,\n icon,\n className,\n children,\n variant = \"segmented\",\n size = \"sm\",\n alwaysShowLabel = false,\n tooltipRootProps,\n}: TooltipButtonProps) => {\n const showTooltip =\n (variant === \"segmented\" && !active) || variant === \"icon-button\";\n\n const showChildren = active || alwaysShowLabel;\n\n // Create the button element based on variant\n const buttonElement = useMemo(() => {\n if (variant === \"segmented\") {\n return (\n <SegmentedControl\n size={size}\n active={active}\n onClick={onClick}\n leftIcon={icon}\n className={cn(\n \"focus-base transition-colors\",\n active\n ? \"bg-neutral-000 dark:bg-neutral-1100\"\n : \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900\",\n className,\n )}\n >\n {showChildren ? children : null}\n </SegmentedControl>\n );\n }\n\n return (\n <div\n role=\"button\"\n className={cn(\n \"w-8 h-8 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 transition-colors focus-base\",\n className,\n )}\n onClick={onClick}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick?.();\n }\n }}\n tabIndex={0}\n >\n {children}\n </div>\n );\n }, [variant, size, active, onClick, icon, className, showChildren, children]);\n\n if (showTooltip) {\n return (\n <Tooltip\n triggerElement={buttonElement}\n rootProps={tooltipRootProps}\n className=\"ml-0\"\n contentProps={{\n className:\n \"px-2 py-1 bg-neutral-1100 dark:bg-neutral-200 text-neutral-300 dark:text-neutral-1000\",\n }}\n triggerProps={{ className: \"ml-0 h-auto\" }}\n >\n {tooltip}\n </Tooltip>\n );\n }\n\n return buttonElement;\n};\n\nexport default TooltipButton;\n"],"names":["React","useMemo","Tooltip","SegmentedControl","cn","TooltipButton","tooltip","active","onClick","icon","className","children","variant","size","alwaysShowLabel","tooltipRootProps","showTooltip","showChildren","buttonElement","leftIcon","div","role","onKeyDown","e","key","preventDefault","tabIndex","triggerElement","rootProps","contentProps","triggerProps"],"mappings":"AAAA,OAAOA,OAASC,OAAO,KAAQ,OAAQ,AACvC,QAAOC,YAAa,YAAa,AACjC,QAAOC,qBAAgD,qBAAsB,AAC7E,QAAOC,OAAQ,aAAc,CAiB7B,MAAMC,cAAgB,CAAC,CACrBC,OAAO,CACPC,OAAS,KAAK,CACdC,OAAO,CACPC,IAAI,CACJC,SAAS,CACTC,QAAQ,CACRC,QAAU,WAAW,CACrBC,KAAO,IAAI,CACXC,gBAAkB,KAAK,CACvBC,gBAAgB,CACG,IACnB,MAAMC,YACJ,AAACJ,UAAY,aAAe,CAACL,QAAWK,UAAY,cAEtD,MAAMK,aAAeV,QAAUO,gBAG/B,MAAMI,cAAgBjB,QAAQ,KAC5B,GAAIW,UAAY,YAAa,CAC3B,OACE,oBAACT,kBACCU,KAAMA,KACNN,OAAQA,OACRC,QAASA,QACTW,SAAUV,KACVC,UAAWN,GACT,+BACAG,OACI,sCACA,uIACJG,YAGDO,aAAeN,SAAW,KAGjC,CAEA,OACE,oBAACS,OACCC,KAAK,SACLX,UAAWN,GACT,uKACAM,WAEFF,QAASA,QACTc,UAAW,AAACC,IACV,GAAIA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,IAAK,CACtCD,EAAEE,cAAc,GAChBjB,WACF,CACF,EACAkB,SAAU,GAETf,SAGP,EAAG,CAACC,QAASC,KAAMN,OAAQC,QAASC,KAAMC,UAAWO,aAAcN,SAAS,EAE5E,GAAIK,YAAa,CACf,OACE,oBAACd,SACCyB,eAAgBT,cAChBU,UAAWb,iBACXL,UAAU,OACVmB,aAAc,CACZnB,UACE,uFACJ,EACAoB,aAAc,CAAEpB,UAAW,aAAc,GAExCJ,QAGP,CAEA,OAAOY,aACT,CAEA,gBAAeb,aAAc"}
@@ -1,2 +1,2 @@
1
- const languages={javascript:{label:"JavaScript",icon:"icon-tech-javascript",syntaxHighlighterKey:"javascript"},typescript:{label:"TypeScript",icon:"icon-tech-typescript",syntaxHighlighterKey:"typescript"},java:{label:"Java",icon:"icon-tech-java",syntaxHighlighterKey:"java"},kotlin:{label:"Kotlin",icon:"icon-tech-kotlin",syntaxHighlighterKey:"kotlin"},python:{label:"Python",icon:"icon-tech-python",syntaxHighlighterKey:"python"},csharp:{label:"C#",icon:"icon-tech-csharp",syntaxHighlighterKey:"csharp"},go:{label:"Go",icon:"icon-tech-go",syntaxHighlighterKey:"go"},ruby:{label:"Ruby",icon:"icon-tech-ruby",syntaxHighlighterKey:"ruby"},php:{label:"PHP",icon:"icon-tech-php",syntaxHighlighterKey:"php"},nodejs:{label:"Node.js",icon:"icon-tech-nodejs",syntaxHighlighterKey:"javascript"},react:{label:"React",icon:"icon-tech-react",syntaxHighlighterKey:"javascript"},html:{label:"HTML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},shell:{label:"Shell",icon:"icon-tech-web",syntaxHighlighterKey:"bash"},json:{label:"JSON",icon:"icon-tech-json",syntaxHighlighterKey:"json"},xml:{label:"XML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},sql:{label:"SQL",icon:"icon-tech-postgres",syntaxHighlighterKey:"sql"},swift:{label:"Swift",icon:"icon-tech-swift",syntaxHighlighterKey:"swift"},cpp:{label:"C++",icon:"icon-tech-web",syntaxHighlighterKey:"cpp"},dart:{label:"Dart",icon:"icon-tech-web",syntaxHighlighterKey:"dart"},objc:{label:"Objective-C",icon:"icon-tech-objectivec",syntaxHighlighterKey:"objc"},android:{label:"Android",icon:"icon-tech-android-head",syntaxHighlighterKey:"java"},flutter:{label:"Flutter",icon:"icon-tech-flutter",syntaxHighlighterKey:"dart"}};export const stripSdkType=lang=>{if(lang.startsWith("realtime_")||lang.startsWith("rest_")){return lang.split("_").slice(1).join("_")}return lang};export const getLanguageInfo=langKey=>{const key=stripSdkType(langKey).toLowerCase();if(languages[key]){return languages[key]}return{label:langKey,icon:"icon-tech-web",syntaxHighlighterKey:langKey}};export default languages;
1
+ export const SDK_PREFIXES=["realtime","rest","client","agent"];const languages={javascript:{label:"JavaScript",icon:"icon-tech-javascript",syntaxHighlighterKey:"javascript"},typescript:{label:"TypeScript",icon:"icon-tech-typescript",syntaxHighlighterKey:"typescript"},java:{label:"Java",icon:"icon-tech-java",syntaxHighlighterKey:"java"},kotlin:{label:"Kotlin",icon:"icon-tech-kotlin",syntaxHighlighterKey:"kotlin"},python:{label:"Python",icon:"icon-tech-python",syntaxHighlighterKey:"python"},csharp:{label:"C#",icon:"icon-tech-csharp",syntaxHighlighterKey:"csharp"},go:{label:"Go",icon:"icon-tech-go",syntaxHighlighterKey:"go"},ruby:{label:"Ruby",icon:"icon-tech-ruby",syntaxHighlighterKey:"ruby"},php:{label:"PHP",icon:"icon-tech-php",syntaxHighlighterKey:"php"},nodejs:{label:"Node.js",icon:"icon-tech-nodejs",syntaxHighlighterKey:"javascript"},react:{label:"React",icon:"icon-tech-react",syntaxHighlighterKey:"javascript"},html:{label:"HTML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},shell:{label:"Shell",icon:"icon-tech-web",syntaxHighlighterKey:"bash"},json:{label:"JSON",icon:"icon-tech-json",syntaxHighlighterKey:"json"},laravel:{label:"Laravel",icon:"icon-tech-laravel-broadcast",syntaxHighlighterKey:"php"},xml:{label:"XML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},sql:{label:"SQL",icon:"icon-tech-postgres",syntaxHighlighterKey:"sql"},swift:{label:"Swift",icon:"icon-tech-swift",syntaxHighlighterKey:"swift"},cpp:{label:"C++",icon:"icon-tech-web",syntaxHighlighterKey:"cpp"},dart:{label:"Dart",icon:"icon-tech-web",syntaxHighlighterKey:"dart"},objc:{label:"Objective-C",icon:"icon-tech-objectivec",syntaxHighlighterKey:"objc"},android:{label:"Android",icon:"icon-tech-android-full",syntaxHighlighterKey:"kotlin"},flutter:{label:"Flutter",icon:"icon-tech-flutter",syntaxHighlighterKey:"dart"}};export const stripSdkType=lang=>{for(const prefix of SDK_PREFIXES){const withUnderscore=`${prefix}_`;if(lang.startsWith(withUnderscore)){return lang.slice(withUnderscore.length)}}return lang};export const getLanguageInfo=langKey=>{const key=stripSdkType(langKey).toLowerCase();if(languages[key]){return languages[key]}return{label:langKey,icon:"icon-tech-web",syntaxHighlighterKey:langKey}};export default languages;
2
2
  //# sourceMappingURL=languages.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/CodeSnippet/languages.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport interface LanguageInfo {\n label: string;\n icon: IconName;\n syntaxHighlighterKey?: string;\n}\n\nexport type LanguageMap = Record<string, LanguageInfo>;\n\nconst languages: LanguageMap = {\n javascript: {\n label: \"JavaScript\",\n icon: \"icon-tech-javascript\",\n syntaxHighlighterKey: \"javascript\",\n },\n typescript: {\n label: \"TypeScript\",\n icon: \"icon-tech-typescript\",\n syntaxHighlighterKey: \"typescript\",\n },\n java: {\n label: \"Java\",\n icon: \"icon-tech-java\",\n syntaxHighlighterKey: \"java\",\n },\n kotlin: {\n label: \"Kotlin\",\n icon: \"icon-tech-kotlin\",\n syntaxHighlighterKey: \"kotlin\",\n },\n python: {\n label: \"Python\",\n icon: \"icon-tech-python\",\n syntaxHighlighterKey: \"python\",\n },\n csharp: {\n label: \"C#\",\n icon: \"icon-tech-csharp\",\n syntaxHighlighterKey: \"csharp\",\n },\n go: {\n label: \"Go\",\n icon: \"icon-tech-go\",\n syntaxHighlighterKey: \"go\",\n },\n ruby: {\n label: \"Ruby\",\n icon: \"icon-tech-ruby\",\n syntaxHighlighterKey: \"ruby\",\n },\n php: {\n label: \"PHP\",\n icon: \"icon-tech-php\",\n syntaxHighlighterKey: \"php\",\n },\n nodejs: {\n label: \"Node.js\",\n icon: \"icon-tech-nodejs\",\n syntaxHighlighterKey: \"javascript\",\n },\n react: {\n label: \"React\",\n icon: \"icon-tech-react\",\n syntaxHighlighterKey: \"javascript\",\n },\n html: {\n label: \"HTML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n shell: {\n label: \"Shell\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"bash\",\n },\n json: {\n label: \"JSON\",\n icon: \"icon-tech-json\",\n syntaxHighlighterKey: \"json\",\n },\n xml: {\n label: \"XML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n sql: {\n label: \"SQL\",\n icon: \"icon-tech-postgres\",\n syntaxHighlighterKey: \"sql\",\n },\n swift: {\n label: \"Swift\",\n icon: \"icon-tech-swift\",\n syntaxHighlighterKey: \"swift\",\n },\n // New entries from languageInfo.ts\n cpp: {\n label: \"C++\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"cpp\",\n },\n dart: {\n label: \"Dart\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"dart\",\n },\n objc: {\n label: \"Objective-C\",\n icon: \"icon-tech-objectivec\",\n syntaxHighlighterKey: \"objc\",\n },\n android: {\n label: \"Android\",\n icon: \"icon-tech-android-head\",\n syntaxHighlighterKey: \"java\",\n },\n flutter: {\n label: \"Flutter\",\n icon: \"icon-tech-flutter\",\n syntaxHighlighterKey: \"dart\",\n },\n};\n\nexport const stripSdkType = (lang: string) => {\n if (lang.startsWith(\"realtime_\") || lang.startsWith(\"rest_\")) {\n return lang.split(\"_\").slice(1).join(\"_\");\n }\n return lang;\n};\n\n// Fallback function to handle languages not in the map\nexport const getLanguageInfo = (langKey: string): LanguageInfo => {\n const key = stripSdkType(langKey).toLowerCase();\n\n if (languages[key]) {\n return languages[key];\n }\n\n // Fallback for unknown languages\n return {\n label: langKey,\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: langKey,\n };\n};\n\nexport default languages;\n"],"names":["languages","javascript","label","icon","syntaxHighlighterKey","typescript","java","kotlin","python","csharp","go","ruby","php","nodejs","react","html","shell","json","xml","sql","swift","cpp","dart","objc","android","flutter","stripSdkType","lang","startsWith","split","slice","join","getLanguageInfo","langKey","key","toLowerCase"],"mappings":"AAUA,MAAMA,UAAyB,CAC7BC,WAAY,CACVC,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAC,WAAY,CACVH,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAE,KAAM,CACJJ,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAG,OAAQ,CACNL,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAI,OAAQ,CACNN,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAK,OAAQ,CACNP,MAAO,KACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAM,GAAI,CACFR,MAAO,KACPC,KAAM,eACNC,qBAAsB,IACxB,EACAO,KAAM,CACJT,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAQ,IAAK,CACHV,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAS,OAAQ,CACNX,MAAO,UACPC,KAAM,mBACNC,qBAAsB,YACxB,EACAU,MAAO,CACLZ,MAAO,QACPC,KAAM,kBACNC,qBAAsB,YACxB,EACAW,KAAM,CACJb,MAAO,OACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAY,MAAO,CACLd,MAAO,QACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAa,KAAM,CACJf,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAc,IAAK,CACHhB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAe,IAAK,CACHjB,MAAO,MACPC,KAAM,qBACNC,qBAAsB,KACxB,EACAgB,MAAO,CACLlB,MAAO,QACPC,KAAM,kBACNC,qBAAsB,OACxB,EAEAiB,IAAK,CACHnB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAkB,KAAM,CACJpB,MAAO,OACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAmB,KAAM,CACJrB,MAAO,cACPC,KAAM,uBACNC,qBAAsB,MACxB,EACAoB,QAAS,CACPtB,MAAO,UACPC,KAAM,yBACNC,qBAAsB,MACxB,EACAqB,QAAS,CACPvB,MAAO,UACPC,KAAM,oBACNC,qBAAsB,MACxB,CACF,CAEA,QAAO,MAAMsB,aAAe,AAACC,OAC3B,GAAIA,KAAKC,UAAU,CAAC,cAAgBD,KAAKC,UAAU,CAAC,SAAU,CAC5D,OAAOD,KAAKE,KAAK,CAAC,KAAKC,KAAK,CAAC,GAAGC,IAAI,CAAC,IACvC,CACA,OAAOJ,IACT,CAAE,AAGF,QAAO,MAAMK,gBAAkB,AAACC,UAC9B,MAAMC,IAAMR,aAAaO,SAASE,WAAW,GAE7C,GAAInC,SAAS,CAACkC,IAAI,CAAE,CAClB,OAAOlC,SAAS,CAACkC,IAAI,AACvB,CAGA,MAAO,CACLhC,MAAO+B,QACP9B,KAAM,gBACNC,qBAAsB6B,OACxB,CACF,CAAE,AAEF,gBAAejC,SAAU"}
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/languages.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport interface LanguageInfo {\n label: string;\n icon: IconName;\n syntaxHighlighterKey?: string;\n}\n\nexport type LanguageMap = Record<string, LanguageInfo>;\n\nexport const SDK_PREFIXES = [\"realtime\", \"rest\", \"client\", \"agent\"] as const;\nexport type SDKType = (typeof SDK_PREFIXES)[number];\n\nconst languages: LanguageMap = {\n javascript: {\n label: \"JavaScript\",\n icon: \"icon-tech-javascript\",\n syntaxHighlighterKey: \"javascript\",\n },\n typescript: {\n label: \"TypeScript\",\n icon: \"icon-tech-typescript\",\n syntaxHighlighterKey: \"typescript\",\n },\n java: {\n label: \"Java\",\n icon: \"icon-tech-java\",\n syntaxHighlighterKey: \"java\",\n },\n kotlin: {\n label: \"Kotlin\",\n icon: \"icon-tech-kotlin\",\n syntaxHighlighterKey: \"kotlin\",\n },\n python: {\n label: \"Python\",\n icon: \"icon-tech-python\",\n syntaxHighlighterKey: \"python\",\n },\n csharp: {\n label: \"C#\",\n icon: \"icon-tech-csharp\",\n syntaxHighlighterKey: \"csharp\",\n },\n go: {\n label: \"Go\",\n icon: \"icon-tech-go\",\n syntaxHighlighterKey: \"go\",\n },\n ruby: {\n label: \"Ruby\",\n icon: \"icon-tech-ruby\",\n syntaxHighlighterKey: \"ruby\",\n },\n php: {\n label: \"PHP\",\n icon: \"icon-tech-php\",\n syntaxHighlighterKey: \"php\",\n },\n nodejs: {\n label: \"Node.js\",\n icon: \"icon-tech-nodejs\",\n syntaxHighlighterKey: \"javascript\",\n },\n react: {\n label: \"React\",\n icon: \"icon-tech-react\",\n syntaxHighlighterKey: \"javascript\",\n },\n html: {\n label: \"HTML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n shell: {\n label: \"Shell\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"bash\",\n },\n json: {\n label: \"JSON\",\n icon: \"icon-tech-json\",\n syntaxHighlighterKey: \"json\",\n },\n laravel: {\n label: \"Laravel\",\n icon: \"icon-tech-laravel-broadcast\",\n syntaxHighlighterKey: \"php\",\n },\n xml: {\n label: \"XML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n sql: {\n label: \"SQL\",\n icon: \"icon-tech-postgres\",\n syntaxHighlighterKey: \"sql\",\n },\n swift: {\n label: \"Swift\",\n icon: \"icon-tech-swift\",\n syntaxHighlighterKey: \"swift\",\n },\n // New entries from languageInfo.ts\n cpp: {\n label: \"C++\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"cpp\",\n },\n dart: {\n label: \"Dart\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"dart\",\n },\n objc: {\n label: \"Objective-C\",\n icon: \"icon-tech-objectivec\",\n syntaxHighlighterKey: \"objc\",\n },\n android: {\n label: \"Android\",\n icon: \"icon-tech-android-full\",\n syntaxHighlighterKey: \"kotlin\",\n },\n flutter: {\n label: \"Flutter\",\n icon: \"icon-tech-flutter\",\n syntaxHighlighterKey: \"dart\",\n },\n};\n\nexport const stripSdkType = (lang: string) => {\n for (const prefix of SDK_PREFIXES) {\n const withUnderscore = `${prefix}_`;\n if (lang.startsWith(withUnderscore)) {\n return lang.slice(withUnderscore.length);\n }\n }\n return lang;\n};\n\n// Fallback function to handle languages not in the map\nexport const getLanguageInfo = (langKey: string): LanguageInfo => {\n const key = stripSdkType(langKey).toLowerCase();\n\n if (languages[key]) {\n return languages[key];\n }\n\n // Fallback for unknown languages\n return {\n label: langKey,\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: langKey,\n };\n};\n\nexport default languages;\n"],"names":["SDK_PREFIXES","languages","javascript","label","icon","syntaxHighlighterKey","typescript","java","kotlin","python","csharp","go","ruby","php","nodejs","react","html","shell","json","laravel","xml","sql","swift","cpp","dart","objc","android","flutter","stripSdkType","lang","prefix","withUnderscore","startsWith","slice","length","getLanguageInfo","langKey","key","toLowerCase"],"mappings":"AAUA,OAAO,MAAMA,aAAe,CAAC,WAAY,OAAQ,SAAU,QAAQ,AAAU,CAG7E,MAAMC,UAAyB,CAC7BC,WAAY,CACVC,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAC,WAAY,CACVH,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAE,KAAM,CACJJ,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAG,OAAQ,CACNL,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAI,OAAQ,CACNN,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAK,OAAQ,CACNP,MAAO,KACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAM,GAAI,CACFR,MAAO,KACPC,KAAM,eACNC,qBAAsB,IACxB,EACAO,KAAM,CACJT,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAQ,IAAK,CACHV,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAS,OAAQ,CACNX,MAAO,UACPC,KAAM,mBACNC,qBAAsB,YACxB,EACAU,MAAO,CACLZ,MAAO,QACPC,KAAM,kBACNC,qBAAsB,YACxB,EACAW,KAAM,CACJb,MAAO,OACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAY,MAAO,CACLd,MAAO,QACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAa,KAAM,CACJf,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAc,QAAS,CACPhB,MAAO,UACPC,KAAM,8BACNC,qBAAsB,KACxB,EACAe,IAAK,CACHjB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAgB,IAAK,CACHlB,MAAO,MACPC,KAAM,qBACNC,qBAAsB,KACxB,EACAiB,MAAO,CACLnB,MAAO,QACPC,KAAM,kBACNC,qBAAsB,OACxB,EAEAkB,IAAK,CACHpB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAmB,KAAM,CACJrB,MAAO,OACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAoB,KAAM,CACJtB,MAAO,cACPC,KAAM,uBACNC,qBAAsB,MACxB,EACAqB,QAAS,CACPvB,MAAO,UACPC,KAAM,yBACNC,qBAAsB,QACxB,EACAsB,QAAS,CACPxB,MAAO,UACPC,KAAM,oBACNC,qBAAsB,MACxB,CACF,CAEA,QAAO,MAAMuB,aAAe,AAACC,OAC3B,IAAK,MAAMC,UAAU9B,aAAc,CACjC,MAAM+B,eAAiB,CAAC,EAAED,OAAO,CAAC,CAAC,CACnC,GAAID,KAAKG,UAAU,CAACD,gBAAiB,CACnC,OAAOF,KAAKI,KAAK,CAACF,eAAeG,MAAM,CACzC,CACF,CACA,OAAOL,IACT,CAAE,AAGF,QAAO,MAAMM,gBAAkB,AAACC,UAC9B,MAAMC,IAAMT,aAAaQ,SAASE,WAAW,GAE7C,GAAIrC,SAAS,CAACoC,IAAI,CAAE,CAClB,OAAOpC,SAAS,CAACoC,IAAI,AACvB,CAGA,MAAO,CACLlC,MAAOiC,QACPhC,KAAM,gBACNC,qBAAsB+B,OACxB,CACF,CAAE,AAEF,gBAAenC,SAAU"}
@@ -0,0 +1,2 @@
1
+ import{describe,expect,it}from"vitest";import{stripSdkType,getLanguageInfo,SDK_PREFIXES}from"./languages";describe("SDK_PREFIXES",()=>{it("contains the expected SDK types",()=>{expect(SDK_PREFIXES).toEqual(["realtime","rest","client","agent"])});it("derives SDKType correctly",()=>{const types=[...SDK_PREFIXES];expect(types).toHaveLength(4)})});describe("stripSdkType",()=>{it("strips realtime_ prefix",()=>{expect(stripSdkType("realtime_javascript")).toBe("javascript")});it("strips rest_ prefix",()=>{expect(stripSdkType("rest_python")).toBe("python")});it("strips client_ prefix",()=>{expect(stripSdkType("client_javascript")).toBe("javascript")});it("strips agent_ prefix",()=>{expect(stripSdkType("agent_python")).toBe("python")});it("returns the language unchanged when no prefix",()=>{expect(stripSdkType("javascript")).toBe("javascript")});it("handles languages with underscores after the prefix",()=>{expect(stripSdkType("client_objective_c")).toBe("objective_c")});it("does not strip unknown prefixes",()=>{expect(stripSdkType("unknown_javascript")).toBe("unknown_javascript")});it("handles empty string",()=>{expect(stripSdkType("")).toBe("")});it("does not strip prefix without underscore",()=>{expect(stripSdkType("realtimejavascript")).toBe("realtimejavascript")})});describe("getLanguageInfo",()=>{it("returns info for known languages",()=>{const info=getLanguageInfo("javascript");expect(info.label).toBe("JavaScript");expect(info.icon).toBe("icon-tech-javascript");expect(info.syntaxHighlighterKey).toBe("javascript")});it("returns info for prefixed languages by stripping prefix first",()=>{const info=getLanguageInfo("realtime_javascript");expect(info.label).toBe("JavaScript");expect(info.icon).toBe("icon-tech-javascript")});it("returns info for client_ prefixed languages",()=>{const info=getLanguageInfo("client_python");expect(info.label).toBe("Python");expect(info.icon).toBe("icon-tech-python")});it("returns info for agent_ prefixed languages",()=>{const info=getLanguageInfo("agent_nodejs");expect(info.label).toBe("Node.js");expect(info.icon).toBe("icon-tech-nodejs")});it("handles case-insensitive lookup",()=>{const info=getLanguageInfo("JavaScript");expect(info.label).toBe("JavaScript")});it("returns fallback for unknown languages",()=>{const info=getLanguageInfo("brainfuck");expect(info.label).toBe("brainfuck");expect(info.icon).toBe("icon-tech-web");expect(info.syntaxHighlighterKey).toBe("brainfuck")});it("returns correct info for new language entries",()=>{expect(getLanguageInfo("cpp").label).toBe("C++");expect(getLanguageInfo("dart").label).toBe("Dart");expect(getLanguageInfo("objc").label).toBe("Objective-C");expect(getLanguageInfo("android").label).toBe("Android");expect(getLanguageInfo("flutter").label).toBe("Flutter")});it("maps languages to correct syntax highlighter keys",()=>{expect(getLanguageInfo("nodejs").syntaxHighlighterKey).toBe("javascript");expect(getLanguageInfo("react").syntaxHighlighterKey).toBe("javascript");expect(getLanguageInfo("flutter").syntaxHighlighterKey).toBe("dart");expect(getLanguageInfo("android").syntaxHighlighterKey).toBe("kotlin");expect(getLanguageInfo("laravel").syntaxHighlighterKey).toBe("php")})});
2
+ //# sourceMappingURL=languages.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/CodeSnippet/languages.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport {\n stripSdkType,\n getLanguageInfo,\n SDK_PREFIXES,\n SDKType,\n} from \"./languages\";\n\ndescribe(\"SDK_PREFIXES\", () => {\n it(\"contains the expected SDK types\", () => {\n expect(SDK_PREFIXES).toEqual([\"realtime\", \"rest\", \"client\", \"agent\"]);\n });\n\n it(\"derives SDKType correctly\", () => {\n // Verify the type system works by assigning each prefix\n const types: SDKType[] = [...SDK_PREFIXES];\n expect(types).toHaveLength(4);\n });\n});\n\ndescribe(\"stripSdkType\", () => {\n it(\"strips realtime_ prefix\", () => {\n expect(stripSdkType(\"realtime_javascript\")).toBe(\"javascript\");\n });\n\n it(\"strips rest_ prefix\", () => {\n expect(stripSdkType(\"rest_python\")).toBe(\"python\");\n });\n\n it(\"strips client_ prefix\", () => {\n expect(stripSdkType(\"client_javascript\")).toBe(\"javascript\");\n });\n\n it(\"strips agent_ prefix\", () => {\n expect(stripSdkType(\"agent_python\")).toBe(\"python\");\n });\n\n it(\"returns the language unchanged when no prefix\", () => {\n expect(stripSdkType(\"javascript\")).toBe(\"javascript\");\n });\n\n it(\"handles languages with underscores after the prefix\", () => {\n expect(stripSdkType(\"client_objective_c\")).toBe(\"objective_c\");\n });\n\n it(\"does not strip unknown prefixes\", () => {\n expect(stripSdkType(\"unknown_javascript\")).toBe(\"unknown_javascript\");\n });\n\n it(\"handles empty string\", () => {\n expect(stripSdkType(\"\")).toBe(\"\");\n });\n\n it(\"does not strip prefix without underscore\", () => {\n expect(stripSdkType(\"realtimejavascript\")).toBe(\"realtimejavascript\");\n });\n});\n\ndescribe(\"getLanguageInfo\", () => {\n it(\"returns info for known languages\", () => {\n const info = getLanguageInfo(\"javascript\");\n expect(info.label).toBe(\"JavaScript\");\n expect(info.icon).toBe(\"icon-tech-javascript\");\n expect(info.syntaxHighlighterKey).toBe(\"javascript\");\n });\n\n it(\"returns info for prefixed languages by stripping prefix first\", () => {\n const info = getLanguageInfo(\"realtime_javascript\");\n expect(info.label).toBe(\"JavaScript\");\n expect(info.icon).toBe(\"icon-tech-javascript\");\n });\n\n it(\"returns info for client_ prefixed languages\", () => {\n const info = getLanguageInfo(\"client_python\");\n expect(info.label).toBe(\"Python\");\n expect(info.icon).toBe(\"icon-tech-python\");\n });\n\n it(\"returns info for agent_ prefixed languages\", () => {\n const info = getLanguageInfo(\"agent_nodejs\");\n expect(info.label).toBe(\"Node.js\");\n expect(info.icon).toBe(\"icon-tech-nodejs\");\n });\n\n it(\"handles case-insensitive lookup\", () => {\n const info = getLanguageInfo(\"JavaScript\");\n expect(info.label).toBe(\"JavaScript\");\n });\n\n it(\"returns fallback for unknown languages\", () => {\n const info = getLanguageInfo(\"brainfuck\");\n expect(info.label).toBe(\"brainfuck\");\n expect(info.icon).toBe(\"icon-tech-web\");\n expect(info.syntaxHighlighterKey).toBe(\"brainfuck\");\n });\n\n it(\"returns correct info for new language entries\", () => {\n expect(getLanguageInfo(\"cpp\").label).toBe(\"C++\");\n expect(getLanguageInfo(\"dart\").label).toBe(\"Dart\");\n expect(getLanguageInfo(\"objc\").label).toBe(\"Objective-C\");\n expect(getLanguageInfo(\"android\").label).toBe(\"Android\");\n expect(getLanguageInfo(\"flutter\").label).toBe(\"Flutter\");\n });\n\n it(\"maps languages to correct syntax highlighter keys\", () => {\n expect(getLanguageInfo(\"nodejs\").syntaxHighlighterKey).toBe(\"javascript\");\n expect(getLanguageInfo(\"react\").syntaxHighlighterKey).toBe(\"javascript\");\n expect(getLanguageInfo(\"flutter\").syntaxHighlighterKey).toBe(\"dart\");\n expect(getLanguageInfo(\"android\").syntaxHighlighterKey).toBe(\"kotlin\");\n expect(getLanguageInfo(\"laravel\").syntaxHighlighterKey).toBe(\"php\");\n });\n});\n"],"names":["describe","expect","it","stripSdkType","getLanguageInfo","SDK_PREFIXES","toEqual","types","toHaveLength","toBe","info","label","icon","syntaxHighlighterKey"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import React,{useState,useEffect,Children,isValidElement,useRef,useCallback,useMemo}from"react";import Code from"./Code";import cn from"./utils/cn";import Icon from"./Icon";import{getLanguageInfo,stripSdkType}from"./CodeSnippet/languages";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import useCopyToClipboard from"./utils/useCopyToClipboard";import PlainCodeView from"./CodeSnippet/PlainCodeView";import CopyButton from"./CodeSnippet/CopyButton";import TooltipButton from"./CodeSnippet/TooltipButton";const substituteApiKey=(content,apiKey,mask=true)=>{return content.replace(/\{\{API_KEY\}\}/g,mask?`${apiKey.split(":")[0]}:*****`:apiKey)};const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk,showCodeLines=true,languageOrdering})=>{const codeRef=useRef(null);const{isCopied,copy}=useCopyToClipboard();const[selectedApiKey,setSelectedApiKey]=useState(()=>apiKeys?.[0]?.keys?.[0]?.key??"");useEffect(()=>{if(!selectedApiKey&&apiKeys&&apiKeys.length>0){setSelectedApiKey(apiKeys[0].keys?.[0]?.key)}},[apiKeys,selectedApiKey]);useEffect(()=>{const element=codeRef.current;if(!element)return;const unmaskRenderedApiKey=(content,apiKey)=>{return content.replace(/(['"]?)([^:'"]+):\*{5}\1/g,`$1${apiKey}$1`)};const handleCopy=event=>{const selection=window.getSelection();if(!selection||selection.rangeCount===0)return;const selectedText=selection.toString();if(!selectedText)return;const range=selection.getRangeAt(0);if(!element.contains(range.commonAncestorContainer))return;const modifiedText=unmaskRenderedApiKey(selectedText,selectedApiKey);event.clipboardData?.setData("text/plain",modifiedText);event.preventDefault()};document.addEventListener("copy",handleCopy);return()=>{document.removeEventListener("copy",handleCopy)}},[codeRef.current,selectedApiKey]);const extractLanguageFromCode=useCallback(codeElement=>{if(!codeElement||!codeElement.props.className)return null;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return null;return langClass.substring(9)},[]);const{codeData,languages,sdkTypes,isSinglePlainCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const codeData=[];const isSinglePlainCommand=childrenArray.length===1&&["language-shell","language-text"].some(lang=>isValidElement(childrenArray[0])&&isValidElement(childrenArray[0].props.children)&&childrenArray[0].props.children.props.className?.includes(lang));childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement)return;const codeLanguage=extractLanguageFromCode(codeElement);if(!codeLanguage)return;if(codeLanguage.startsWith("realtime_")){sdkTypes.add("realtime")}else if(codeLanguage.startsWith("rest_")){sdkTypes.add("rest")}if(!languages.includes(codeLanguage)){languages.push(codeLanguage)}const codeContent=codeElement.props.children;codeData.push({language:codeLanguage,content:codeContent})});return{codeData,languages,sdkTypes,isSinglePlainCommand}},[children,extractLanguageFromCode]);const showSDKSelector=sdkTypes.size>0;const filteredLanguages=useMemo(()=>{const filtered=!sdk||!showSDKSelector?[...languages]:languages.filter(lang=>lang.startsWith(`${sdk}_`));if(languageOrdering&&languageOrdering.length>0){filtered.sort((a,b)=>{const aBase=stripSdkType(a);const bBase=stripSdkType(b);const aIndex=languageOrdering.indexOf(aBase);const bIndex=languageOrdering.indexOf(bBase);if(aIndex!==-1&&bIndex!==-1)return aIndex-bIndex;if(aIndex!==-1)return-1;if(bIndex!==-1)return 1;return 0})}return filtered},[sdk,showSDKSelector,languages,languageOrdering]);const activeLanguage=useMemo(()=>{if(sdk&&sdkTypes.has(sdk)){return`${sdk}_${lang}`}if(lang)return lang;if(filteredLanguages.length>0)return filteredLanguages[0];return languages[0]},[lang,sdk,sdkTypes,filteredLanguages]);const requiresApiKeySubstitution=useMemo(()=>{const containsPlaceholder=codeData.some(code=>code?.content.includes("{{API_KEY}}")&&code?.language===lang);return containsPlaceholder&&!!apiKeys&&apiKeys.length>0&&!!selectedApiKey},[codeData,apiKeys,selectedApiKey,lang]);const[isHovering,setIsHovering]=useState(false);const hasOnlyJsonSnippet=useMemo(()=>languages.length===1&&languages[0]==="json",[languages]);const processedChildren=useMemo(()=>{if(!activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":activeLanguage;return codeData.filter(code=>{return code?.language===targetLanguage}).map(code=>{if(!code)return null;const cleanLang=hasOnlyJsonSnippet?"json":code.language;const langInfo=getLanguageInfo(cleanLang??"");if(typeof code.content==="string"||typeof code.content==="number"||typeof code.content==="boolean"){let processedContent=String(code.content);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}if(!langInfo.syntaxHighlighterKey||!cleanLang)return null;return React.createElement(Code,{key:code.language,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:processedContent,additionalCSS:"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-6 py-4",showLines:showCodeLines})}return null})},[activeLanguage,codeData,hasOnlyJsonSnippet,showCodeLines,apiKeys,selectedApiKey]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return codeData.some(code=>{return code?.language===activeLanguage})},[activeLanguage,hasOnlyJsonSnippet,codeData]);const handleSDKTypeChange=useCallback(type=>{const nextLang=stripSdkType(languages.find(l=>l===`${type}_${stripSdkType(activeLanguage)}`)??languages.find(l=>l.startsWith(`${type}_`))??activeLanguage);if(onChange&&nextLang){onChange(stripSdkType(activeLanguage),type)}},[languages]);const handleLanguageChange=useCallback(language=>{if(onChange){onChange(stripSdkType(language),sdk)}},[onChange,sdk]);const NoSnippetMessage=useMemo(()=>{if(!activeLanguage)return()=>null;const activeLanguageInfo=getLanguageInfo(activeLanguage);return()=>React.createElement("div",{className:"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center"},React.createElement(Icon,{name:"icon-gui-exclamation-triangle-outline",color:"text-yellow-600 dark:text-yellow-400",size:"24px"}),React.createElement("p",{className:"ui-text-p3 text-neutral-700 dark:text-neutral-600"},"You're currently viewing the ",activeLanguageInfo.label," docs. There either isn't a ",activeLanguageInfo.label," code sample for this example, or this feature isn't supported in"," ",activeLanguageInfo.label,". Switch language to view this example in a different language, or check which SDKs support this feature."))},[activeLanguage]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const renderContent=useMemo(()=>{if(!activeLanguage)return null;if(hasSnippetForActiveLanguage){return processedChildren}return React.createElement(NoSnippetMessage,null)},[activeLanguage,hasSnippetForActiveLanguage,processedChildren,NoSnippetMessage]);if(isSinglePlainCommand){const plainChild=codeData[0];if(plainChild){const codeContent=plainChild.content;const language=plainChild.language;if(!language||!codeContent)return null;let processedContent=String(codeContent);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(PlainCodeView,{content:processedContent,className:className,language:language,icon:language==="shell"?"icon-gui-command-line-outline":null})}}return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]",className)},headerRow&&React.createElement("div",{className:"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg"},React.createElement("div",{className:"flex space-x-1.5"},React.createElement("div",{className:"w-3 h-3 rounded-full bg-orange-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-green-500"})),React.createElement("div",{className:"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000"},title),React.createElement("div",{className:"w-12"})),showSDKSelector&&React.createElement("div",{className:cn("p-2 border-b border-neutral-200 dark:border-neutral-1100 h-14",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-3 justify-start"},sdkTypes.has("realtime")&&React.createElement(TooltipButton,{tooltip:"Realtime SDK",active:sdk==="realtime",onClick:()=>handleSDKTypeChange("realtime"),variant:"segmented",size:"sm",alwaysShowLabel:true},"Realtime"),sdkTypes.has("rest")&&React.createElement(TooltipButton,{tooltip:"REST SDK",active:sdk==="rest",onClick:()=>handleSDKTypeChange("rest"),variant:"segmented",size:"sm",alwaysShowLabel:true},"REST"))),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:activeLanguage,onLanguageChange:handleLanguageChange}):React.createElement("div",{className:cn("border-b border-neutral-200 dark:border-neutral-1100 h-[2.125rem] inline-flex items-center px-3 w-full",{"rounded-t-lg":!headerRow})},filteredLanguages.length>0&&React.createElement("div",{className:cn("inline-flex items-center",{"cursor-pointer":filteredLanguages.length>0}),...filteredLanguages.length>0&&{onClick:()=>handleLanguageChange(filteredLanguages[0])}},React.createElement(Icon,{name:getLanguageInfo(filteredLanguages[0]).icon,size:"16px",additionalCSS:"mr-2"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none"},getLanguageInfo(filteredLanguages[0]).label)))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0},renderContent,isHovering&&activeLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=codeData.find(code=>code.language===activeLanguage)?.content;if(text)copy(substituteApiKey(text,selectedApiKey,false))},isCopied:isCopied})),requiresApiKeySubstitution&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:selectedApiKey,onApiKeyChange:setSelectedApiKey}))};export default CodeSnippet;
1
+ import React,{useState,useEffect,Children,isValidElement,useRef,useCallback,useMemo}from"react";import Code from"./Code";import cn from"./utils/cn";import{parseLineHighlights}from"./utils/syntax-highlighter";import Icon from"./Icon";import{getLanguageInfo,stripSdkType,SDK_PREFIXES}from"./CodeSnippet/languages";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import PlainCodeView from"./CodeSnippet/PlainCodeView";import CopyButton from"./CodeSnippet/CopyButton";import SegmentedControl from"./SegmentedControl";const substituteApiKey=(content,apiKey,mask=true)=>{return content.replace(/\{\{API_KEY\}\}/g,mask?`${apiKey.split(":")[0]}:*****`:apiKey)};const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk,showCodeLines=true,languageOrdering,wrapCode=false})=>{const codeRef=useRef(null);const[selectedApiKey,setSelectedApiKey]=useState(()=>apiKeys?.[0]?.keys?.[0]?.key??"");useEffect(()=>{if(!selectedApiKey&&apiKeys&&apiKeys.length>0){setSelectedApiKey(apiKeys[0].keys?.[0]?.key)}},[apiKeys]);useEffect(()=>{const element=codeRef.current;if(!element)return;const unmaskRenderedApiKey=(content,apiKey)=>{return content.replace(/(['"]?)([^:'"]+):\*{5}\1/g,`$1${apiKey}$1`)};const handleCopy=event=>{const selection=window.getSelection();if(!selection||selection.rangeCount===0)return;const selectedText=selection.toString();if(!selectedText)return;const range=selection.getRangeAt(0);if(!element.contains(range.commonAncestorContainer))return;const modifiedText=unmaskRenderedApiKey(selectedText,selectedApiKey);event.clipboardData?.setData("text/plain",modifiedText);event.preventDefault()};document.addEventListener("copy",handleCopy);return()=>{document.removeEventListener("copy",handleCopy)}},[selectedApiKey]);const extractLanguageFromCode=useCallback(codeElement=>{if(!codeElement||!codeElement.props.className)return null;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return null;return langClass.substring(9)},[]);const findCodeElement=useCallback(preChildren=>{if(isValidElement(preChildren)){return preChildren}if(Array.isArray(preChildren)){const codeEl=preChildren.find(c=>isValidElement(c));return codeEl&&isValidElement(codeEl)?codeEl:null}return null},[]);const{codeData,languages,sdkTypes,isSinglePlainCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const codeData=[];const isSinglePlainCommand=childrenArray.length===1&&["language-shell","language-text"].some(lang=>{if(!isValidElement(childrenArray[0]))return false;const codeEl=findCodeElement(childrenArray[0].props.children);return codeEl?.props.className?.includes(lang)});childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=findCodeElement(preElement.props.children);if(!codeElement)return;const rawLanguage=extractLanguageFromCode(codeElement);if(!rawLanguage)return;const meta=codeElement.props?.["data-meta"];const{lang:codeLanguage,highlights:lineHighlights}=parseLineHighlights(rawLanguage,meta);for(const prefix of SDK_PREFIXES){if(codeLanguage.startsWith(`${prefix}_`)){sdkTypes.add(prefix);break}}if(!languages.includes(codeLanguage)){languages.push(codeLanguage)}const codeContent=codeElement.props.children;codeData.push({language:codeLanguage,content:codeContent,lineHighlights})});return{codeData,languages,sdkTypes,isSinglePlainCommand}},[children,extractLanguageFromCode,findCodeElement]);const resolvedSdk=useMemo(()=>{if(sdkTypes.size===1&&sdk&&!sdkTypes.has(sdk)){return Array.from(sdkTypes)[0]}return sdk},[sdk,sdkTypes]);const showSDKSelector=sdkTypes.has("realtime")||sdkTypes.has("rest");const filteredLanguages=useMemo(()=>{const filtered=!resolvedSdk||!showSDKSelector?[...languages]:languages.filter(lang=>lang.startsWith(`${resolvedSdk}_`));if(languageOrdering&&languageOrdering.length>0){filtered.sort((a,b)=>{const aBase=stripSdkType(a);const bBase=stripSdkType(b);const aIndex=languageOrdering.indexOf(aBase);const bIndex=languageOrdering.indexOf(bBase);if(aIndex!==-1&&bIndex!==-1)return aIndex-bIndex;if(aIndex!==-1)return-1;if(bIndex!==-1)return 1;return 0})}return filtered},[resolvedSdk,showSDKSelector,languages,languageOrdering]);const activeLanguage=useMemo(()=>{if(resolvedSdk==="client"||resolvedSdk==="agent"){const fullLang=`${resolvedSdk}_${lang}`;if(languages.includes(fullLang)){return fullLang}const prefixMatch=languages.find(l=>l.startsWith(`${resolvedSdk}_`));if(prefixMatch)return prefixMatch}if(resolvedSdk&&sdkTypes.has(resolvedSdk)){return`${resolvedSdk}_${lang}`}if(lang)return lang;if(filteredLanguages.length>0)return filteredLanguages[0];return languages[0]},[resolvedSdk,sdkTypes,lang,filteredLanguages,languages]);const requiresApiKeySubstitution=useMemo(()=>{const containsPlaceholder=codeData.some(code=>code?.content.includes("{{API_KEY}}"));return containsPlaceholder&&!!apiKeys&&apiKeys.length>0&&!!selectedApiKey},[codeData,apiKeys,selectedApiKey]);const[isHovering,setIsHovering]=useState(false);const hasOnlyJsonSnippet=useMemo(()=>languages.length===1&&languages[0]==="json",[languages]);const processedChildren=useMemo(()=>{if(!activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":activeLanguage;return codeData.filter(code=>{return code?.language===targetLanguage}).map(code=>{if(!code)return null;const cleanLang=hasOnlyJsonSnippet?"json":code.language;const langInfo=getLanguageInfo(cleanLang??"");if(typeof code.content==="string"||typeof code.content==="number"||typeof code.content==="boolean"){let processedContent=String(code.content);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}if(!langInfo.syntaxHighlighterKey||!cleanLang)return null;return React.createElement(Code,{key:code.language,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:processedContent,additionalCSS:"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4",showLines:showCodeLines,wrap:wrapCode,lineHighlights:Object.keys(code.lineHighlights).length>0?code.lineHighlights:undefined})}return null})},[activeLanguage,hasOnlyJsonSnippet,codeData,requiresApiKeySubstitution,showCodeLines,wrapCode,selectedApiKey]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return codeData.some(code=>{return code?.language===activeLanguage})},[activeLanguage,hasOnlyJsonSnippet,codeData]);const handleSDKTypeChange=useCallback(type=>{const nextLang=stripSdkType(languages.find(l=>l===`${type}_${stripSdkType(activeLanguage)}`)??languages.find(l=>l.startsWith(`${type}_`))??activeLanguage);if(onChange&&nextLang){onChange(stripSdkType(activeLanguage),type)}},[activeLanguage,languages,onChange]);const handleLanguageChange=useCallback(language=>{if(onChange){onChange(stripSdkType(language),resolvedSdk)}},[onChange,resolvedSdk]);const noSnippetMessage=useMemo(()=>{if(!activeLanguage)return null;const activeLanguageInfo=getLanguageInfo(activeLanguage);return React.createElement("div",{className:"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center"},React.createElement(Icon,{name:"icon-gui-exclamation-triangle-outline",color:"text-yellow-600 dark:text-yellow-400",size:"24px"}),React.createElement("p",{className:"ui-text-p3 text-neutral-700 dark:text-neutral-600"},"You're currently viewing the ",activeLanguageInfo.label," docs. There either isn't a ",activeLanguageInfo.label," code sample for this example, or this feature isn't supported in"," ",activeLanguageInfo.label,". Switch language to view this example in a different language, or check which SDKs support this feature."))},[activeLanguage]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const showFixedLanguageLabel=fixed&&activeLanguage;const renderLanguageLabel=(langKey,onClick)=>React.createElement("div",{className:cn("border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full",{"rounded-t-lg":!headerRow})},React.createElement("div",{className:cn("inline-flex items-center",onClick&&"cursor-pointer"),...onClick&&{onClick}},React.createElement(Icon,{name:getLanguageInfo(langKey).icon,size:"16px",additionalCSS:"mr-2"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none"},getLanguageInfo(langKey).label)));const renderContent=useMemo(()=>{if(!activeLanguage)return null;if(hasSnippetForActiveLanguage){return processedChildren}return noSnippetMessage},[activeLanguage,hasSnippetForActiveLanguage,processedChildren,noSnippetMessage]);if(isSinglePlainCommand){const plainChild=codeData[0];if(plainChild){const codeContent=plainChild.content;const language=plainChild.language;if(!language||!codeContent)return null;let processedContent=String(codeContent);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(PlainCodeView,{content:processedContent,className:className,language:language,icon:language==="shell"?"icon-gui-command-line-outline":null})}}return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]",className)},headerRow&&React.createElement("div",{className:"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg"},React.createElement("div",{className:"flex space-x-1.5"},React.createElement("div",{className:"w-3 h-3 rounded-full bg-orange-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-green-500"})),React.createElement("div",{className:"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000"},title),React.createElement("div",{className:"w-12"})),showSDKSelector&&React.createElement("div",{className:cn("p-2 border-b border-neutral-300 dark:border-neutral-1000",sdkTypes.size===1&&"p-1",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-1 justify-start"},["realtime","rest"].map(type=>sdkTypes.has(type)&&React.createElement(SegmentedControl,{key:type,onClick:()=>handleSDKTypeChange(type),size:"xs",active:resolvedSdk===type,className:cn("text-[11px] font-semibold px-2 py-1 h-auto",sdkTypes.size===1&&"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500",sdkTypes.size>1&&resolvedSdk!==type&&"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900",sdkTypes.size>1&&resolvedSdk===type&&"bg-neutral-000 dark:bg-neutral-1100")},type==="realtime"?"Realtime":"REST")))),showFixedLanguageLabel&&renderLanguageLabel(activeLanguage),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:activeLanguage,onLanguageChange:handleLanguageChange}):renderLanguageLabel(filteredLanguages[0],()=>handleLanguageChange(filteredLanguages[0]))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false)},renderContent,isHovering&&activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=codeData.find(code=>code.language===activeLanguage)?.content;if(text)navigator.clipboard.writeText(substituteApiKey(text,selectedApiKey,false))}})),requiresApiKeySubstitution&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:selectedApiKey,onApiKeyChange:setSelectedApiKey}))};export default CodeSnippet;
2
2
  //# sourceMappingURL=CodeSnippet.js.map