@djangocfg/ui-tools 2.1.418 → 2.1.419

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 (304) hide show
  1. package/dist/file-icon/index.cjs +3 -3
  2. package/dist/file-icon/index.cjs.map +1 -1
  3. package/dist/file-icon/index.mjs +3 -3
  4. package/dist/file-icon/index.mjs.map +1 -1
  5. package/package.json +93 -28
  6. package/src/common/FloatingToolbar/actions/CopyAction.tsx +31 -0
  7. package/src/{components → common}/FloatingToolbar/actions/DownloadAction.tsx +15 -10
  8. package/src/common/FloatingToolbar/actions/ExpandAction.tsx +33 -0
  9. package/src/common/FloatingToolbar/actions/FullscreenAction.tsx +38 -0
  10. package/src/{components → common}/FloatingToolbar/index.tsx +39 -0
  11. package/src/lib/http.ts +64 -0
  12. package/src/tools/chat/index.ts +1 -1
  13. package/src/tools/chat/launcher/ChatFAB.tsx +66 -74
  14. package/src/tools/chat/launcher/header/ChatHeaderActionButton.tsx +2 -3
  15. package/src/tools/chat/lazy.tsx +1 -1
  16. package/src/tools/chat/messages/MessageBubble.tsx +1 -1
  17. package/src/tools/chat/messages/blocks/builtin.tsx +1 -1
  18. package/src/tools/chat/messages/blocks/renderers/CodeBlock.tsx +2 -2
  19. package/src/tools/chat/messages/blocks/renderers/JsonBlock.tsx +12 -1
  20. package/src/tools/data/DataGrid/lazy.tsx +1 -1
  21. package/src/tools/data/DataTable/lazy.tsx +1 -1
  22. package/src/tools/data/JsonTree/JsonViewer.tsx +720 -0
  23. package/src/tools/data/JsonTree/README.md +126 -73
  24. package/src/tools/data/JsonTree/index.tsx +3 -95
  25. package/src/tools/data/JsonTree/lazy.tsx +10 -50
  26. package/src/tools/data/JsonTree/types.ts +82 -63
  27. package/src/tools/data/Kanban/lazy.tsx +1 -1
  28. package/src/tools/data/Listbox/lazy.tsx +1 -1
  29. package/src/tools/data/Masonry/lazy.tsx +1 -1
  30. package/src/tools/data/Timeline/lazy.tsx +1 -1
  31. package/src/tools/data/Tree/lazy.tsx +1 -1
  32. package/src/tools/dev/Map/lazy.tsx +1 -1
  33. package/src/tools/dev/Mermaid/Mermaid.client.tsx +2 -2
  34. package/src/tools/dev/Mermaid/lazy.tsx +1 -1
  35. package/src/tools/dev/api/ApiRefTable/ApiRefTable.tsx +65 -0
  36. package/src/tools/dev/api/ApiRefTable/README.md +31 -0
  37. package/src/tools/dev/api/ApiRefTable/components/Row.tsx +96 -0
  38. package/src/tools/dev/api/ApiRefTable/components/TypeDisplay.tsx +44 -0
  39. package/src/tools/dev/api/ApiRefTable/index.ts +6 -0
  40. package/src/tools/dev/api/ApiRefTable/lazy.tsx +21 -0
  41. package/src/tools/dev/api/ApiRefTable/types.ts +82 -0
  42. package/src/tools/dev/api/ApiRefTable/utils.ts +42 -0
  43. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/ApiIntroSection.tsx +1 -1
  44. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/index.tsx +1 -1
  45. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/index.tsx +1 -1
  46. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/ResponseBody.tsx +7 -21
  47. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/RequestPanel.tsx +1 -1
  48. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/PrettyView.tsx +13 -19
  49. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/types.ts +1 -1
  50. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/lazy.tsx +1 -1
  51. package/src/tools/dev/api/RequestViewer/README.md +33 -0
  52. package/src/tools/dev/api/RequestViewer/RequestViewer.tsx +121 -0
  53. package/src/tools/dev/api/RequestViewer/components/BodyTab.tsx +44 -0
  54. package/src/tools/dev/api/RequestViewer/components/EmptyState.tsx +13 -0
  55. package/src/tools/dev/api/RequestViewer/components/HeadersTab.tsx +78 -0
  56. package/src/tools/dev/api/RequestViewer/components/TimingTab.tsx +113 -0
  57. package/src/tools/dev/api/RequestViewer/components/utils.ts +31 -0
  58. package/src/tools/dev/api/RequestViewer/index.ts +16 -0
  59. package/src/tools/dev/api/RequestViewer/lazy.tsx +30 -0
  60. package/src/tools/dev/api/RequestViewer/types.ts +81 -0
  61. package/src/tools/dev/code/DiffViewer/DiffViewer.tsx +144 -0
  62. package/src/tools/dev/code/DiffViewer/README.md +33 -0
  63. package/src/tools/dev/code/DiffViewer/components/CopyButton.tsx +49 -0
  64. package/src/tools/dev/code/DiffViewer/components/DiffLineContent.tsx +48 -0
  65. package/src/tools/dev/code/DiffViewer/components/SplitView.tsx +220 -0
  66. package/src/tools/dev/code/DiffViewer/components/UnifiedView.tsx +154 -0
  67. package/src/tools/dev/code/DiffViewer/hooks/useDiff.ts +47 -0
  68. package/src/tools/dev/code/DiffViewer/hooks/useHighlighter.ts +54 -0
  69. package/src/tools/dev/code/DiffViewer/index.ts +22 -0
  70. package/src/tools/dev/code/DiffViewer/lazy.tsx +22 -0
  71. package/src/tools/dev/code/DiffViewer/types.ts +109 -0
  72. package/src/tools/dev/code/DiffViewer/utils/computeDiff.ts +159 -0
  73. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/CollapseToggle.tsx +1 -1
  74. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/MarkdownMessage.tsx +1 -1
  75. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/components.tsx +2 -2
  76. package/src/tools/dev/{PrettyCode → code/PrettyCode}/PrettyCode.client.tsx +2 -2
  77. package/src/tools/dev/{PrettyCode → code/PrettyCode}/lazy.tsx +1 -1
  78. package/src/tools/dev/ops/EnvTable/EnvTable.tsx +228 -0
  79. package/src/tools/dev/ops/EnvTable/README.md +29 -0
  80. package/src/tools/dev/ops/EnvTable/hooks/useEnvMask.ts +121 -0
  81. package/src/tools/dev/ops/EnvTable/index.ts +12 -0
  82. package/src/tools/dev/ops/EnvTable/lazy.tsx +21 -0
  83. package/src/tools/dev/ops/EnvTable/types.ts +76 -0
  84. package/src/tools/dev/ops/LogViewer/LogViewer.tsx +194 -0
  85. package/src/tools/dev/ops/LogViewer/README.md +30 -0
  86. package/src/tools/dev/ops/LogViewer/components/LogRow.tsx +151 -0
  87. package/src/tools/dev/ops/LogViewer/components/Toolbar.tsx +199 -0
  88. package/src/tools/dev/ops/LogViewer/hooks/useAutoScroll.ts +68 -0
  89. package/src/tools/dev/ops/LogViewer/hooks/useLogFilter.ts +58 -0
  90. package/src/tools/dev/ops/LogViewer/index.ts +18 -0
  91. package/src/tools/dev/ops/LogViewer/lazy.tsx +25 -0
  92. package/src/tools/dev/ops/LogViewer/types.ts +142 -0
  93. package/src/tools/dev/ops/LogViewer/utils/ansi.ts +231 -0
  94. package/src/tools/forms/CodeEditor/hooks/useEditorTheme.ts +13 -73
  95. package/src/tools/forms/CodeEditor/lazy.tsx +1 -1
  96. package/src/tools/forms/FileUpload/lazy.tsx +1 -1
  97. package/src/tools/forms/JsonEditor/JsonEditor.tsx +115 -0
  98. package/src/tools/forms/JsonEditor/index.ts +1 -0
  99. package/src/tools/forms/JsonEditor/lazy.tsx +24 -0
  100. package/src/tools/forms/JsonForm/index.ts +1 -1
  101. package/src/tools/forms/JsonForm/lazy.tsx +1 -1
  102. package/src/tools/forms/MarkdownEditor/lazy.tsx +1 -1
  103. package/src/tools/forms/NotionEditor/README.md +237 -0
  104. package/src/tools/forms/NotionEditor/lazy.tsx +1 -1
  105. package/src/tools/index.ts +153 -13
  106. package/src/tools/input/Combobox/lazy.tsx +1 -1
  107. package/src/tools/input/CronScheduler/components/CronPreview.README.md +28 -0
  108. package/src/tools/input/CronScheduler/components/CronPreview.tsx +136 -0
  109. package/src/tools/input/CronScheduler/components/index.ts +3 -0
  110. package/src/tools/input/CronScheduler/index.tsx +5 -1
  111. package/src/tools/input/CronScheduler/lazy.tsx +5 -1
  112. package/src/tools/input/CronScheduler/utils/cron-next-runs.ts +122 -0
  113. package/src/tools/input/CronScheduler/utils/index.ts +1 -0
  114. package/src/tools/input/Scroller/lazy.tsx +1 -1
  115. package/src/tools/input/Sortable/lazy.tsx +1 -1
  116. package/src/tools/input/SpeechRecognition/lazy.tsx +1 -1
  117. package/src/tools/input/SpeechRecognition/widgets/VoiceComposerSlot.tsx +41 -36
  118. package/src/tools/media/ImageViewer/components/ImageToolbar.tsx +58 -47
  119. package/src/tools/media/ImageViewer/components/ImageViewer.tsx +27 -19
  120. package/src/tools/media/ImageViewer/lazy.tsx +1 -1
  121. package/src/tools/media/LottiePlayer/lazy.tsx +1 -1
  122. package/src/tools/media/VideoPlayer/VideoPlayer.tsx +28 -1
  123. package/src/tools/media/VideoPlayer/parts/fullscreen.tsx +21 -4
  124. package/src/tools/media/VideoPlayer/parts/pip.tsx +21 -4
  125. package/src/tools/media/VideoPlayer/parts/play-button.tsx +21 -4
  126. package/src/tools/media/VideoPlayer/parts/playback-rate.tsx +19 -3
  127. package/src/tools/media/VideoPlayer/parts/volume.tsx +237 -18
  128. package/src/tools/media/VideoPlayer/styles/video-player.css +87 -7
  129. package/src/tools/overlay/ResponsiveDialog/lazy.tsx +1 -1
  130. package/src/tools/overlay/ScrollSpy/lazy.tsx +1 -1
  131. package/src/tools/overlay/SelectionToolbar/lazy.tsx +1 -1
  132. package/src/tools/overlay/Tour/lazy.tsx +1 -1
  133. package/src/tools/visual/Marquee/lazy.tsx +1 -1
  134. package/src/tools/visual/QRCode/lazy.tsx +1 -1
  135. package/src/tools/visual/charts/ActivityGraph/ActivityGraph.tsx +195 -0
  136. package/src/tools/visual/charts/ActivityGraph/README.md +28 -0
  137. package/src/tools/visual/charts/ActivityGraph/index.ts +8 -0
  138. package/src/tools/visual/charts/ActivityGraph/lazy.tsx +21 -0
  139. package/src/tools/visual/charts/ActivityGraph/types.ts +59 -0
  140. package/src/tools/visual/charts/ActivityGraph/utils.ts +88 -0
  141. package/src/tools/visual/charts/CommitGraph/CommitGraph.tsx +80 -0
  142. package/src/tools/visual/charts/CommitGraph/README.md +28 -0
  143. package/src/tools/visual/charts/CommitGraph/components/CommitDetail.tsx +107 -0
  144. package/src/tools/visual/charts/CommitGraph/components/CommitRow.tsx +122 -0
  145. package/src/tools/visual/charts/CommitGraph/components/Rails.tsx +171 -0
  146. package/src/tools/visual/charts/CommitGraph/hooks/useGraphLayout.ts +169 -0
  147. package/src/tools/visual/charts/CommitGraph/hooks/useLaneColors.ts +45 -0
  148. package/src/tools/visual/charts/CommitGraph/index.ts +14 -0
  149. package/src/tools/visual/charts/CommitGraph/lazy.tsx +25 -0
  150. package/src/tools/visual/charts/CommitGraph/types.ts +85 -0
  151. package/src/tools/visual/charts/CommitGraph/utils.ts +53 -0
  152. package/src/tools/visual/{Gauge → charts/Gauge}/lazy.tsx +1 -1
  153. package/src/tools/visual/charts/Sparkline/README.md +29 -0
  154. package/src/tools/visual/charts/Sparkline/Sparkline.tsx +217 -0
  155. package/src/tools/visual/charts/Sparkline/index.ts +9 -0
  156. package/src/tools/visual/charts/Sparkline/lazy.tsx +26 -0
  157. package/src/tools/visual/charts/Sparkline/types.ts +58 -0
  158. package/src/tools/visual/design/ColorPalette/ColorPalette.tsx +129 -0
  159. package/src/tools/visual/design/ColorPalette/README.md +34 -0
  160. package/src/tools/visual/design/ColorPalette/components/Swatch.tsx +102 -0
  161. package/src/tools/visual/design/ColorPalette/hooks/useCopyToClipboard.ts +41 -0
  162. package/src/tools/visual/design/ColorPalette/index.ts +12 -0
  163. package/src/tools/visual/design/ColorPalette/lazy.tsx +21 -0
  164. package/src/tools/visual/design/ColorPalette/types.ts +63 -0
  165. package/src/tools/visual/design/ColorPalette/utils.ts +83 -0
  166. package/src/tools/visual/{ColorPicker → design/ColorPicker}/lazy.tsx +1 -1
  167. package/src/tools/visual/{FileIcon → design/FileIcon}/treeAdapter.tsx +1 -1
  168. package/src/tools/visual/{Fps → indicators/Fps}/lazy.tsx +1 -1
  169. package/src/tools/visual/{Rating → indicators/Rating}/lazy.tsx +1 -1
  170. package/src/tools/visual/indicators/StatusIndicator/README.md +28 -0
  171. package/src/tools/visual/indicators/StatusIndicator/StatusIndicator.tsx +83 -0
  172. package/src/tools/visual/indicators/StatusIndicator/index.ts +14 -0
  173. package/src/tools/visual/indicators/StatusIndicator/lazy.tsx +21 -0
  174. package/src/tools/visual/indicators/StatusIndicator/types.ts +133 -0
  175. package/src/components/FloatingToolbar/actions/CopyAction.tsx +0 -22
  176. package/src/components/FloatingToolbar/actions/ExpandAction.tsx +0 -25
  177. package/src/components/FloatingToolbar/actions/FullscreenAction.tsx +0 -30
  178. package/src/tools/data/JsonTree/components/JsonContent.tsx +0 -197
  179. package/src/tools/data/JsonTree/hooks/useJsonExpand.ts +0 -50
  180. /package/src/{components → common}/FloatingToolbar/FloatingToolbar.css +0 -0
  181. /package/src/{components → common}/FloatingToolbar/actions/index.ts +0 -0
  182. /package/src/{components → common}/FloatingToolbar/hooks/useElementCorner.ts +0 -0
  183. /package/src/{components → common}/FloatingToolbar/hooks/useScrollIsolation.ts +0 -0
  184. /package/src/{components → common}/index.ts +0 -0
  185. /package/src/{components → common}/lazy-wrapper.tsx +0 -0
  186. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/README.md +0 -0
  187. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/DocsView.tsx +0 -0
  188. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/LanguageTabs.tsx +0 -0
  189. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/useCodeSnippet.ts +0 -0
  190. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/MetaActions.tsx +0 -0
  191. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/MethodBadge.tsx +0 -0
  192. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/PathDisplay.tsx +0 -0
  193. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/ParamGroup.tsx +0 -0
  194. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/ParamRow.tsx +0 -0
  195. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/index.tsx +0 -0
  196. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/RequestBody/index.tsx +0 -0
  197. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/ResponseRow.tsx +0 -0
  198. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/StatusTag.tsx +0 -0
  199. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/index.tsx +0 -0
  200. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/FieldRow.tsx +0 -0
  201. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts +0 -0
  202. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/index.tsx +0 -0
  203. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/types.ts +0 -0
  204. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/SectionHeader.tsx +0 -0
  205. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/defaults.ts +0 -0
  206. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/index.tsx +0 -0
  207. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/context.tsx +0 -0
  208. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/hooks/useSectionHash.ts +0 -0
  209. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/index.tsx +0 -0
  210. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/store/index.ts +0 -0
  211. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/store/selectors.ts +0 -0
  212. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/types.ts +0 -0
  213. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/SchemaCopyMenu.tsx +0 -0
  214. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/BrandHeader.tsx +0 -0
  215. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/CategoryBlock.tsx +0 -0
  216. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/EndpointRow.tsx +0 -0
  217. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SchemaSection.tsx +0 -0
  218. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SearchInput.tsx +0 -0
  219. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SidebarBody.tsx +0 -0
  220. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/Toolbar.tsx +0 -0
  221. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/buildVM.ts +0 -0
  222. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/index.tsx +0 -0
  223. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/types.ts +0 -0
  224. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/useDebouncedValue.ts +0 -0
  225. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/SlideInPlayground.tsx +0 -0
  226. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/TryItSheet.tsx +0 -0
  227. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/anchor.ts +0 -0
  228. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/grouping.ts +0 -0
  229. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/index.tsx +0 -0
  230. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/sidebarLabel.ts +0 -0
  231. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/index.ts +0 -0
  232. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/BodyFormEditor.tsx +0 -0
  233. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/EndpointDraftSync.tsx +0 -0
  234. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/EndpointResetButton.tsx +0 -0
  235. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/PreviewView.tsx +0 -0
  236. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/RawView.tsx +0 -0
  237. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/StatusBar.tsx +0 -0
  238. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/ViewTabs.tsx +0 -0
  239. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/detectContent.ts +0 -0
  240. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/index.tsx +0 -0
  241. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/useResponseView.ts +0 -0
  242. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/SendButton.tsx +0 -0
  243. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ui.tsx +0 -0
  244. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/constants.ts +0 -0
  245. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/context/PlaygroundContext.tsx +0 -0
  246. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/index.ts +0 -0
  247. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useDocsUrlSync.ts +0 -0
  248. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useEndpointDraft.ts +0 -0
  249. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useMobile.ts +0 -0
  250. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useOpenApiSchema.ts +0 -0
  251. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/index.tsx +0 -0
  252. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/types.ts +0 -0
  253. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/apiKeyManager.ts +0 -0
  254. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/codeSamples.ts +0 -0
  255. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/formatters.ts +0 -0
  256. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/index.ts +0 -0
  257. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/operationToHar.ts +0 -0
  258. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/sampler.ts +0 -0
  259. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/schemaExport.ts +0 -0
  260. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/scrollParent.ts +0 -0
  261. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/url.ts +0 -0
  262. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/versionManager.ts +0 -0
  263. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/ActionRow.tsx +0 -0
  264. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/ChatMessageRow.tsx +0 -0
  265. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/CodeBlock.tsx +0 -0
  266. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/README.md +0 -0
  267. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/index.ts +0 -0
  268. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/linkRules.ts +0 -0
  269. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/plainText.ts +0 -0
  270. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/sanitize.ts +0 -0
  271. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/types.ts +0 -0
  272. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/README.md +0 -0
  273. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/index.tsx +0 -0
  274. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/registerPrismLanguages.ts +0 -0
  275. /package/src/tools/visual/{Gauge → charts/Gauge}/Gauge.tsx +0 -0
  276. /package/src/tools/visual/{Gauge → charts/Gauge}/index.ts +0 -0
  277. /package/src/tools/visual/{Gauge → charts/Gauge}/types.ts +0 -0
  278. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/ColorPicker.tsx +0 -0
  279. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/ColorPickerContext.tsx +0 -0
  280. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/ColorPickerStore.tsx +0 -0
  281. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/index.ts +0 -0
  282. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/index.ts +0 -0
  283. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/lib/color-utils.ts +0 -0
  284. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerAlphaSlider.tsx +0 -0
  285. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerArea.tsx +0 -0
  286. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerEyeDropper.tsx +0 -0
  287. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerFormatSelect.tsx +0 -0
  288. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerHueSlider.tsx +0 -0
  289. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerInput.tsx +0 -0
  290. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerSwatch.tsx +0 -0
  291. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/index.ts +0 -0
  292. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/types.ts +0 -0
  293. /package/src/tools/visual/{FileIcon → design/FileIcon}/FileIcon.tsx +0 -0
  294. /package/src/tools/visual/{FileIcon → design/FileIcon}/get-file-icon.ts +0 -0
  295. /package/src/tools/visual/{FileIcon → design/FileIcon}/icons/icon-data.ts +0 -0
  296. /package/src/tools/visual/{FileIcon → design/FileIcon}/index.ts +0 -0
  297. /package/src/tools/visual/{FileIcon → design/FileIcon}/loader.ts +0 -0
  298. /package/src/tools/visual/{FileIcon → design/FileIcon}/specialFolders.ts +0 -0
  299. /package/src/tools/visual/{Fps → indicators/Fps}/Fps.tsx +0 -0
  300. /package/src/tools/visual/{Fps → indicators/Fps}/index.ts +0 -0
  301. /package/src/tools/visual/{Fps → indicators/Fps}/types.ts +0 -0
  302. /package/src/tools/visual/{Rating → indicators/Rating}/Rating.tsx +0 -0
  303. /package/src/tools/visual/{Rating → indicators/Rating}/index.ts +0 -0
  304. /package/src/tools/visual/{Rating → indicators/Rating}/types.ts +0 -0
@@ -0,0 +1,199 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import * as React from 'react';
6
+ import {
7
+ ArrowDownToLine,
8
+ Circle,
9
+ Pause,
10
+ Play,
11
+ Search,
12
+ Terminal,
13
+ Trash2,
14
+ X,
15
+ } from 'lucide-react';
16
+ import { cn } from '@djangocfg/ui-core/lib';
17
+ import type { LogLevel } from '../types';
18
+ import { LEVEL_LABELS, getLevelToneClasses } from '../types';
19
+
20
+ interface ToolbarButtonProps {
21
+ onClick: () => void;
22
+ label: string;
23
+ active?: boolean;
24
+ children: React.ReactNode;
25
+ }
26
+
27
+ function ToolbarButton({ onClick, label, active, children }: ToolbarButtonProps) {
28
+ return (
29
+ <button
30
+ type="button"
31
+ onClick={onClick}
32
+ aria-label={label}
33
+ aria-pressed={active}
34
+ className={cn(
35
+ 'inline-flex size-7 items-center justify-center rounded-md outline-none transition-colors',
36
+ 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',
37
+ 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1',
38
+ active && 'bg-accent text-accent-foreground',
39
+ )}
40
+ >
41
+ {children}
42
+ </button>
43
+ );
44
+ }
45
+
46
+ export interface ToolbarProps {
47
+ title: string;
48
+ totalCount: number;
49
+ filteredCount: number;
50
+ levels: LogLevel[];
51
+ activeLevels: Set<LogLevel>;
52
+ toggleLevel: (level: LogLevel) => void;
53
+ levelCounts: Partial<Record<LogLevel, number>>;
54
+ searchQuery: string;
55
+ setSearchQuery: (q: string) => void;
56
+ autoScrollEnabled: boolean;
57
+ paused: boolean;
58
+ setPaused: (p: boolean) => void;
59
+ onClear?: () => void;
60
+ }
61
+
62
+ /**
63
+ * Header + filter row for the LogViewer. The level chips also serve as
64
+ * the count badges — clicking strikes them out and removes the level
65
+ * from the active set. The search input is always visible (no expand /
66
+ * collapse toggle) because filter and search are the two main jobs of
67
+ * the toolbar; hiding either is friction.
68
+ */
69
+ export function Toolbar({
70
+ title,
71
+ totalCount,
72
+ filteredCount,
73
+ levels,
74
+ activeLevels,
75
+ toggleLevel,
76
+ levelCounts,
77
+ searchQuery,
78
+ setSearchQuery,
79
+ autoScrollEnabled,
80
+ paused,
81
+ setPaused,
82
+ onClear,
83
+ }: ToolbarProps) {
84
+ return (
85
+ <div className="flex flex-col gap-2 border-b border-border/40 bg-muted/30 px-3 py-2">
86
+ <div className="flex items-center gap-2">
87
+ <Terminal className="size-3.5 shrink-0 text-muted-foreground" />
88
+ <span className="flex-1 truncate text-sm font-medium text-foreground">
89
+ {title}
90
+ </span>
91
+
92
+ <span className="mr-1 text-[10px] tabular-nums text-muted-foreground">
93
+ {filteredCount}
94
+ {filteredCount !== totalCount && ` / ${totalCount}`} lines
95
+ </span>
96
+
97
+ <div className="flex items-center gap-0.5">
98
+ {autoScrollEnabled && (
99
+ <ToolbarButton
100
+ onClick={() => setPaused(!paused)}
101
+ label={paused ? 'Resume auto-scroll' : 'Pause auto-scroll'}
102
+ active={paused}
103
+ >
104
+ {paused ? (
105
+ <Play className="size-3.5" />
106
+ ) : (
107
+ <Pause className="size-3.5" />
108
+ )}
109
+ </ToolbarButton>
110
+ )}
111
+
112
+ {onClear && (
113
+ <ToolbarButton onClick={onClear} label="Clear logs">
114
+ <Trash2 className="size-3.5" />
115
+ </ToolbarButton>
116
+ )}
117
+ </div>
118
+ </div>
119
+
120
+ <div className="flex flex-wrap items-center gap-2">
121
+ <div className="flex flex-wrap items-center gap-1">
122
+ {levels.map((level) => {
123
+ const tone = getLevelToneClasses(level);
124
+ const isActive = activeLevels.has(level);
125
+ const count = levelCounts[level] ?? 0;
126
+ return (
127
+ <button
128
+ key={level}
129
+ type="button"
130
+ onClick={() => toggleLevel(level)}
131
+ role="checkbox"
132
+ aria-checked={isActive}
133
+ aria-label={`${isActive ? 'Hide' : 'Show'} ${level} logs`}
134
+ className={cn(
135
+ 'inline-flex items-center gap-1 rounded-md px-2 py-1 text-[11px] font-medium outline-none transition-colors',
136
+ 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1',
137
+ isActive
138
+ ? tone.badge
139
+ : 'bg-muted/50 text-muted-foreground/60 line-through',
140
+ )}
141
+ >
142
+ <Circle
143
+ className={cn(
144
+ 'size-1.5 fill-current',
145
+ isActive ? tone.text : 'text-muted-foreground/40',
146
+ )}
147
+ />
148
+ {LEVEL_LABELS[level]}
149
+ {count > 0 && <span className="tabular-nums">{count}</span>}
150
+ </button>
151
+ );
152
+ })}
153
+ </div>
154
+
155
+ <div className="ml-auto flex items-center gap-1.5 rounded-md border border-border/40 bg-background px-2 py-1">
156
+ <Search className="size-3 text-muted-foreground" />
157
+ <input
158
+ type="text"
159
+ value={searchQuery}
160
+ onChange={(e) => setSearchQuery(e.target.value)}
161
+ placeholder="Filter…"
162
+ aria-label="Filter logs"
163
+ className="w-32 bg-transparent text-xs text-foreground outline-none placeholder:text-muted-foreground sm:w-40"
164
+ />
165
+ {searchQuery && (
166
+ <button
167
+ type="button"
168
+ onClick={() => setSearchQuery('')}
169
+ className="inline-flex size-4 items-center justify-center rounded text-muted-foreground hover:text-foreground"
170
+ aria-label="Clear search"
171
+ >
172
+ <X className="size-3" />
173
+ </button>
174
+ )}
175
+ </div>
176
+ </div>
177
+ </div>
178
+ );
179
+ }
180
+
181
+ export interface ScrollToBottomPillProps {
182
+ visible: boolean;
183
+ onClick: () => void;
184
+ }
185
+
186
+ export function ScrollToBottomPill({ visible, onClick }: ScrollToBottomPillProps) {
187
+ if (!visible) return null;
188
+ return (
189
+ <button
190
+ type="button"
191
+ onClick={onClick}
192
+ className="flex w-full items-center justify-center gap-1.5 border-t border-border/40 bg-muted/30 py-1.5 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground"
193
+ aria-label="Scroll to latest"
194
+ >
195
+ <ArrowDownToLine className="size-3" />
196
+ New logs below
197
+ </button>
198
+ );
199
+ }
@@ -0,0 +1,68 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import * as React from 'react';
6
+ import type { VirtuosoHandle } from 'react-virtuoso';
7
+
8
+ /**
9
+ * Sticky-bottom controller for the virtualized log list. Tracks whether
10
+ * the viewport is pinned to the latest entry; when it is and a new entry
11
+ * arrives, jumps to the end via Virtuoso's `scrollToIndex`. When the
12
+ * user has scrolled up, the controller stays out of the way and exposes
13
+ * `scrollToBottom` so the UI can offer a "Jump to latest" pill.
14
+ *
15
+ * The previous (DOM-scroll) implementation set `scrollTop = scrollHeight`
16
+ * inside an effect. That works for a non-virtualized list but fights
17
+ * Virtuoso, which owns the scroller. We instead use Virtuoso's
18
+ * `atBottomStateChange` callback (fired with hysteresis) and call
19
+ * `scrollToIndex` when new entries land while we're pinned.
20
+ */
21
+ export interface UseAutoScrollResult {
22
+ virtuosoRef: React.RefObject<VirtuosoHandle | null>;
23
+ isAtBottom: boolean;
24
+ /** Wire to Virtuoso's `atBottomStateChange`. */
25
+ onAtBottomChange: (atBottom: boolean) => void;
26
+ /** Jump to the end of the list. Used by the "New logs below" pill. */
27
+ scrollToBottom: () => void;
28
+ }
29
+
30
+ export function useAutoScroll(
31
+ entryCount: number,
32
+ enabled: boolean,
33
+ ): UseAutoScrollResult {
34
+ const virtuosoRef = React.useRef<VirtuosoHandle | null>(null);
35
+ const [isAtBottom, setIsAtBottom] = React.useState(true);
36
+ const isAtBottomRef = React.useRef(true);
37
+ const lastCountRef = React.useRef(entryCount);
38
+
39
+ const onAtBottomChange = React.useCallback((atBottom: boolean) => {
40
+ isAtBottomRef.current = atBottom;
41
+ setIsAtBottom(atBottom);
42
+ }, []);
43
+
44
+ const scrollToBottom = React.useCallback(() => {
45
+ const handle = virtuosoRef.current;
46
+ if (!handle) return;
47
+ // `LAST` is Virtuoso's sentinel for "bottom".
48
+ handle.scrollToIndex({ index: 'LAST', behavior: 'auto' });
49
+ isAtBottomRef.current = true;
50
+ setIsAtBottom(true);
51
+ }, []);
52
+
53
+ React.useEffect(() => {
54
+ const prev = lastCountRef.current;
55
+ lastCountRef.current = entryCount;
56
+ if (!enabled) return;
57
+ if (entryCount <= prev) return; // shrink / no-op
58
+ if (!isAtBottomRef.current) return;
59
+ // Defer one frame so Virtuoso settles the new row's height first;
60
+ // otherwise the jump lands one row short on the very first append.
61
+ const id = requestAnimationFrame(() => {
62
+ virtuosoRef.current?.scrollToIndex({ index: 'LAST', behavior: 'auto' });
63
+ });
64
+ return () => cancelAnimationFrame(id);
65
+ }, [entryCount, enabled]);
66
+
67
+ return { virtuosoRef, isAtBottom, onAtBottomChange, scrollToBottom };
68
+ }
@@ -0,0 +1,58 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import * as React from 'react';
6
+ import type { LogEntry, LogLevel } from '../types';
7
+ import { stripAnsi } from '../utils/ansi';
8
+
9
+ interface UseLogFilterArgs {
10
+ entries: LogEntry[];
11
+ activeLevels: Set<LogLevel>;
12
+ searchQuery: string;
13
+ }
14
+
15
+ interface UseLogFilterResult {
16
+ filtered: LogEntry[];
17
+ /** Counts per level for the **unfiltered** entries — feeds the filter
18
+ * chip badges. */
19
+ counts: Partial<Record<LogLevel, number>>;
20
+ }
21
+
22
+ /**
23
+ * Filter + search the entry list. Both operations route through one
24
+ * pass over `entries` so a 10k-entry list with both filters active
25
+ * costs one iteration, not two. The result is memoized on the input
26
+ * identity — callers that only append to `entries` get an incremental
27
+ * O(n) re-derivation (acceptable for 10k+; if it ever bites, switch
28
+ * to a streaming filter that reuses the prior result).
29
+ *
30
+ * Search is case-insensitive and strips ANSI escapes from the haystack
31
+ * — a search for `"port 3000"` matches `\x1b[32mport 3000\x1b[0m` too.
32
+ */
33
+ export function useLogFilter({
34
+ entries,
35
+ activeLevels,
36
+ searchQuery,
37
+ }: UseLogFilterArgs): UseLogFilterResult {
38
+ return React.useMemo(() => {
39
+ const counts: Partial<Record<LogLevel, number>> = {};
40
+ const filtered: LogEntry[] = [];
41
+ const needle = searchQuery.trim().toLowerCase();
42
+ const hasSearch = needle.length > 0;
43
+
44
+ for (let i = 0; i < entries.length; i += 1) {
45
+ const entry = entries[i];
46
+ counts[entry.level] = (counts[entry.level] ?? 0) + 1;
47
+
48
+ if (!activeLevels.has(entry.level)) continue;
49
+ if (hasSearch) {
50
+ const haystack = stripAnsi(entry.message).toLowerCase();
51
+ if (!haystack.includes(needle)) continue;
52
+ }
53
+ filtered.push(entry);
54
+ }
55
+
56
+ return { filtered, counts };
57
+ }, [entries, activeLevels, searchQuery]);
58
+ }
@@ -0,0 +1,18 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ export { LogViewer } from './LogViewer';
4
+ export {
5
+ LEVEL_LABELS,
6
+ LEVEL_TONE,
7
+ TONE_CLASSES as LOG_TONE_CLASSES,
8
+ getLevelToneClasses,
9
+ } from './types';
10
+ export type {
11
+ LogEntry,
12
+ LogLevel,
13
+ LogTone,
14
+ LogToneClasses,
15
+ LogViewerProps,
16
+ } from './types';
17
+ export { parseAnsi, stripAnsi } from './utils/ansi';
18
+ export type { AnsiSegment } from './utils/ansi';
@@ -0,0 +1,25 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import { createLazyComponent } from '../../../../common/lazy-wrapper';
6
+ import type { LogViewerProps } from './types';
7
+
8
+ export const LazyLogViewer = createLazyComponent<LogViewerProps>(
9
+ () => import('./LogViewer').then((mod) => ({ default: mod.LogViewer })),
10
+ {
11
+ displayName: 'LazyLogViewer',
12
+ fallback: (
13
+ <div
14
+ data-slot="log-viewer-skeleton"
15
+ className="flex h-[400px] w-full animate-pulse flex-col gap-2 rounded-xl border border-border/60 bg-card p-3"
16
+ >
17
+ <div className="h-7 w-1/3 rounded bg-muted" />
18
+ <div className="h-5 w-2/3 rounded bg-muted" />
19
+ <div className="flex-1 rounded bg-muted/60" />
20
+ </div>
21
+ ),
22
+ },
23
+ );
24
+
25
+ export type { LogViewerProps } from './types';
@@ -0,0 +1,142 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ import type * as React from 'react';
4
+
5
+ /**
6
+ * Severity level of a log entry. Five canonical levels — `error`, `warn`,
7
+ * `info`, `debug` route to status / categorical semantic tokens; `verbose`
8
+ * collapses to muted.
9
+ */
10
+ export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'verbose';
11
+
12
+ /**
13
+ * Tone bucket each level resolves to. `debug` is intentionally **not** a
14
+ * status — it routes through a categorical preset color so themes can
15
+ * rotate it without polluting the destructive/warning/info/success
16
+ * palette.
17
+ */
18
+ export type LogTone = 'destructive' | 'warning' | 'info' | 'debug' | 'muted';
19
+
20
+ export interface LogEntry {
21
+ /** Severity. */
22
+ level: LogLevel;
23
+ /** Log message text. May contain ANSI escape sequences. */
24
+ message: string;
25
+ /** ISO timestamp string. When omitted, the current time is used for display. */
26
+ timestamp?: string;
27
+ }
28
+
29
+ /**
30
+ * Tone CSS class bundle per `LogTone`. Every class resolves to a semantic
31
+ * token (no raw color scales). `dot` and `text` ride on opacity-derived
32
+ * surfaces so they survive every preset that overrides only the base
33
+ * `--{status}` token.
34
+ */
35
+ export interface LogToneClasses {
36
+ /** Text color for the level label / icon. */
37
+ text: string;
38
+ /** Background for the filled dot. */
39
+ dot: string;
40
+ /** Badge surface when the level filter is active. */
41
+ badge: string;
42
+ }
43
+
44
+ /**
45
+ * Mapping from {@link LogLevel} to {@link LogTone}. `debug` collapses to
46
+ * the categorical `debug` tone — it is not a status.
47
+ */
48
+ export const LEVEL_TONE: Record<LogLevel, LogTone> = {
49
+ error: 'destructive',
50
+ warn: 'warning',
51
+ info: 'info',
52
+ debug: 'debug',
53
+ verbose: 'muted',
54
+ };
55
+
56
+ /**
57
+ * Short 3-letter labels rendered in monospace gutters. Matches `ERR`,
58
+ * `WRN`, `INF`, `DBG`, `VRB` so columns align on screen.
59
+ */
60
+ export const LEVEL_LABELS: Record<LogLevel, string> = {
61
+ error: 'ERR',
62
+ warn: 'WRN',
63
+ info: 'INF',
64
+ debug: 'DBG',
65
+ verbose: 'VRB',
66
+ };
67
+
68
+ /**
69
+ * Semantic-token class bundle per {@link LogTone}. All `bg-` / `text-`
70
+ * values resolve through ui-core tokens — themes can swap them without
71
+ * touching this file. `debug` uses a violet-ish categorical via the
72
+ * `--chart-4`/`--chart-5` fallbacks already shipped in ui-core (we keep
73
+ * it on the `muted` family for surface and lean on opacity for
74
+ * differentiation; the actual debug color comes from the level dot in
75
+ * the source).
76
+ */
77
+ export const TONE_CLASSES: Record<LogTone, LogToneClasses> = {
78
+ destructive: {
79
+ text: 'text-destructive',
80
+ dot: 'bg-destructive',
81
+ badge: 'bg-destructive/15 text-destructive',
82
+ },
83
+ warning: {
84
+ text: 'text-warning',
85
+ dot: 'bg-warning',
86
+ badge: 'bg-warning/15 text-warning',
87
+ },
88
+ info: {
89
+ text: 'text-info',
90
+ dot: 'bg-info',
91
+ badge: 'bg-info/15 text-info',
92
+ },
93
+ // `debug` is categorical, not status — render via primary token tinted
94
+ // for legibility; themes that recolour `--primary` get a free debug
95
+ // shift without touching this file.
96
+ debug: {
97
+ text: 'text-primary',
98
+ dot: 'bg-primary',
99
+ badge: 'bg-primary/15 text-primary',
100
+ },
101
+ muted: {
102
+ text: 'text-muted-foreground',
103
+ dot: 'bg-muted-foreground/60',
104
+ badge: 'bg-muted text-muted-foreground',
105
+ },
106
+ };
107
+
108
+ /**
109
+ * Resolve the tone class bundle for a level.
110
+ */
111
+ export function getLevelToneClasses(level: LogLevel): LogToneClasses {
112
+ return TONE_CLASSES[LEVEL_TONE[level]];
113
+ }
114
+
115
+ export interface LogViewerProps
116
+ extends Omit<React.ComponentProps<'div'>, 'children' | 'title'> {
117
+ /** Log entries to render. */
118
+ entries: LogEntry[];
119
+ /** Header title. @default "Logs" */
120
+ title?: string;
121
+ /** Maximum visible height in pixels. @default 400 */
122
+ maxHeight?: number;
123
+ /** Show monospace line numbers. @default true */
124
+ lineNumbers?: boolean;
125
+ /** Show timestamps. @default true */
126
+ timestamps?: boolean;
127
+ /** Auto-scroll to bottom when new entries arrive (and the user is
128
+ * already pinned to the bottom). @default true */
129
+ autoScroll?: boolean;
130
+ /** Levels exposed in the toolbar filter chips. @default all five */
131
+ levels?: LogLevel[];
132
+ /** Interpret ANSI escape sequences (`\x1b[31m…`) in `message`.
133
+ * @default true */
134
+ ansi?: boolean;
135
+ /** Optional callback wired to the "Clear" toolbar button — when
136
+ * omitted, the button is hidden. */
137
+ onClear?: () => void;
138
+ /** Force-disable virtualization (small / Storybook usage). The
139
+ * virtualized path uses `react-virtuoso` and handles 10k+ entries
140
+ * without lag. @default false */
141
+ noVirtualize?: boolean;
142
+ }