@djangocfg/ui-tools 2.1.417 → 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 (335) hide show
  1. package/dist/audio-player/index.cjs +1 -2
  2. package/dist/audio-player/index.cjs.map +1 -1
  3. package/dist/audio-player/index.d.cts +3 -11
  4. package/dist/audio-player/index.d.ts +3 -11
  5. package/dist/audio-player/index.mjs +1 -2
  6. package/dist/audio-player/index.mjs.map +1 -1
  7. package/dist/file-icon/index.cjs +3 -3
  8. package/dist/file-icon/index.cjs.map +1 -1
  9. package/dist/file-icon/index.mjs +3 -3
  10. package/dist/file-icon/index.mjs.map +1 -1
  11. package/dist/tree/index.cjs +0 -3
  12. package/dist/tree/index.cjs.map +1 -1
  13. package/dist/tree/index.mjs +0 -3
  14. package/dist/tree/index.mjs.map +1 -1
  15. package/package.json +117 -36
  16. package/src/common/FloatingToolbar/actions/CopyAction.tsx +31 -0
  17. package/src/{components → common}/FloatingToolbar/actions/DownloadAction.tsx +15 -10
  18. package/src/common/FloatingToolbar/actions/ExpandAction.tsx +33 -0
  19. package/src/common/FloatingToolbar/actions/FullscreenAction.tsx +38 -0
  20. package/src/{components → common}/FloatingToolbar/index.tsx +39 -0
  21. package/src/lib/http.ts +64 -0
  22. package/src/tools/chat/index.ts +1 -1
  23. package/src/tools/chat/launcher/ChatFAB.tsx +66 -74
  24. package/src/tools/chat/launcher/header/ChatHeaderActionButton.tsx +2 -3
  25. package/src/tools/chat/lazy.tsx +1 -1
  26. package/src/tools/chat/messages/MessageBubble.tsx +1 -1
  27. package/src/tools/chat/messages/blocks/builtin.tsx +1 -1
  28. package/src/tools/chat/messages/blocks/renderers/CodeBlock.tsx +2 -2
  29. package/src/tools/chat/messages/blocks/renderers/JsonBlock.tsx +12 -1
  30. package/src/tools/data/DataGrid/lazy.tsx +1 -1
  31. package/src/tools/data/DataTable/lazy.tsx +1 -1
  32. package/src/tools/data/JsonTree/JsonViewer.tsx +720 -0
  33. package/src/tools/data/JsonTree/README.md +126 -73
  34. package/src/tools/data/JsonTree/index.tsx +3 -95
  35. package/src/tools/data/JsonTree/lazy.tsx +10 -50
  36. package/src/tools/data/JsonTree/types.ts +82 -63
  37. package/src/tools/data/Kanban/lazy.tsx +1 -1
  38. package/src/tools/data/Listbox/lazy.tsx +1 -1
  39. package/src/tools/data/Masonry/lazy.tsx +1 -1
  40. package/src/tools/data/Timeline/lazy.tsx +1 -1
  41. package/src/tools/data/Tree/components/TreeRow.tsx +0 -11
  42. package/src/tools/data/Tree/lazy.tsx +1 -1
  43. package/src/tools/dev/Map/lazy.tsx +1 -1
  44. package/src/tools/dev/Mermaid/Mermaid.client.tsx +2 -2
  45. package/src/tools/dev/Mermaid/lazy.tsx +1 -1
  46. package/src/tools/dev/api/ApiRefTable/ApiRefTable.tsx +65 -0
  47. package/src/tools/dev/api/ApiRefTable/README.md +31 -0
  48. package/src/tools/dev/api/ApiRefTable/components/Row.tsx +96 -0
  49. package/src/tools/dev/api/ApiRefTable/components/TypeDisplay.tsx +44 -0
  50. package/src/tools/dev/api/ApiRefTable/index.ts +6 -0
  51. package/src/tools/dev/api/ApiRefTable/lazy.tsx +21 -0
  52. package/src/tools/dev/api/ApiRefTable/types.ts +82 -0
  53. package/src/tools/dev/api/ApiRefTable/utils.ts +42 -0
  54. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/ApiIntroSection.tsx +1 -1
  55. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/index.tsx +1 -1
  56. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/index.tsx +1 -1
  57. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/ResponseBody.tsx +7 -21
  58. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/RequestPanel.tsx +1 -1
  59. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/PrettyView.tsx +13 -19
  60. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/types.ts +1 -1
  61. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/lazy.tsx +1 -1
  62. package/src/tools/dev/api/RequestViewer/README.md +33 -0
  63. package/src/tools/dev/api/RequestViewer/RequestViewer.tsx +121 -0
  64. package/src/tools/dev/api/RequestViewer/components/BodyTab.tsx +44 -0
  65. package/src/tools/dev/api/RequestViewer/components/EmptyState.tsx +13 -0
  66. package/src/tools/dev/api/RequestViewer/components/HeadersTab.tsx +78 -0
  67. package/src/tools/dev/api/RequestViewer/components/TimingTab.tsx +113 -0
  68. package/src/tools/dev/api/RequestViewer/components/utils.ts +31 -0
  69. package/src/tools/dev/api/RequestViewer/index.ts +16 -0
  70. package/src/tools/dev/api/RequestViewer/lazy.tsx +30 -0
  71. package/src/tools/dev/api/RequestViewer/types.ts +81 -0
  72. package/src/tools/dev/code/DiffViewer/DiffViewer.tsx +144 -0
  73. package/src/tools/dev/code/DiffViewer/README.md +33 -0
  74. package/src/tools/dev/code/DiffViewer/components/CopyButton.tsx +49 -0
  75. package/src/tools/dev/code/DiffViewer/components/DiffLineContent.tsx +48 -0
  76. package/src/tools/dev/code/DiffViewer/components/SplitView.tsx +220 -0
  77. package/src/tools/dev/code/DiffViewer/components/UnifiedView.tsx +154 -0
  78. package/src/tools/dev/code/DiffViewer/hooks/useDiff.ts +47 -0
  79. package/src/tools/dev/code/DiffViewer/hooks/useHighlighter.ts +54 -0
  80. package/src/tools/dev/code/DiffViewer/index.ts +22 -0
  81. package/src/tools/dev/code/DiffViewer/lazy.tsx +22 -0
  82. package/src/tools/dev/code/DiffViewer/types.ts +109 -0
  83. package/src/tools/dev/code/DiffViewer/utils/computeDiff.ts +159 -0
  84. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/CollapseToggle.tsx +1 -1
  85. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/MarkdownMessage.tsx +1 -1
  86. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/components.tsx +2 -2
  87. package/src/tools/dev/{PrettyCode → code/PrettyCode}/PrettyCode.client.tsx +2 -2
  88. package/src/tools/dev/{PrettyCode → code/PrettyCode}/lazy.tsx +1 -1
  89. package/src/tools/dev/ops/EnvTable/EnvTable.tsx +228 -0
  90. package/src/tools/dev/ops/EnvTable/README.md +29 -0
  91. package/src/tools/dev/ops/EnvTable/hooks/useEnvMask.ts +121 -0
  92. package/src/tools/dev/ops/EnvTable/index.ts +12 -0
  93. package/src/tools/dev/ops/EnvTable/lazy.tsx +21 -0
  94. package/src/tools/dev/ops/EnvTable/types.ts +76 -0
  95. package/src/tools/dev/ops/LogViewer/LogViewer.tsx +194 -0
  96. package/src/tools/dev/ops/LogViewer/README.md +30 -0
  97. package/src/tools/dev/ops/LogViewer/components/LogRow.tsx +151 -0
  98. package/src/tools/dev/ops/LogViewer/components/Toolbar.tsx +199 -0
  99. package/src/tools/dev/ops/LogViewer/hooks/useAutoScroll.ts +68 -0
  100. package/src/tools/dev/ops/LogViewer/hooks/useLogFilter.ts +58 -0
  101. package/src/tools/dev/ops/LogViewer/index.ts +18 -0
  102. package/src/tools/dev/ops/LogViewer/lazy.tsx +25 -0
  103. package/src/tools/dev/ops/LogViewer/types.ts +142 -0
  104. package/src/tools/dev/ops/LogViewer/utils/ansi.ts +231 -0
  105. package/src/tools/forms/CodeEditor/components/Editor.tsx +19 -0
  106. package/src/tools/forms/CodeEditor/hooks/useEditorTheme.ts +13 -73
  107. package/src/tools/forms/CodeEditor/lazy.tsx +1 -1
  108. package/src/tools/forms/CodeEditor/types/index.ts +7 -0
  109. package/src/tools/forms/FileUpload/lazy.tsx +1 -1
  110. package/src/tools/forms/JsonEditor/JsonEditor.tsx +115 -0
  111. package/src/tools/forms/JsonEditor/index.ts +1 -0
  112. package/src/tools/forms/JsonEditor/lazy.tsx +24 -0
  113. package/src/tools/forms/JsonForm/index.ts +1 -1
  114. package/src/tools/forms/JsonForm/lazy.tsx +1 -1
  115. package/src/tools/forms/MarkdownEditor/MarkdownEditor.tsx +40 -0
  116. package/src/tools/forms/MarkdownEditor/lazy.tsx +1 -1
  117. package/src/tools/forms/MarkdownEditor/styles.css +174 -21
  118. package/src/tools/forms/NotionEditor/CustomKeymap.ts +48 -0
  119. package/src/tools/forms/NotionEditor/LinkDialog.tsx +133 -0
  120. package/src/tools/forms/NotionEditor/NotionEditor.tsx +304 -0
  121. package/src/tools/forms/NotionEditor/README.md +237 -0
  122. package/src/tools/forms/NotionEditor/SlashExtension.ts +32 -0
  123. package/src/tools/forms/NotionEditor/SlashList.tsx +136 -0
  124. package/src/tools/forms/NotionEditor/TaskItemView.tsx +41 -0
  125. package/src/tools/forms/NotionEditor/createSlashSuggestion.ts +121 -0
  126. package/src/tools/forms/NotionEditor/extensions.ts +105 -0
  127. package/src/tools/forms/NotionEditor/index.ts +1 -0
  128. package/src/tools/forms/NotionEditor/lazy.tsx +44 -0
  129. package/src/tools/forms/NotionEditor/slashItems.ts +159 -0
  130. package/src/tools/forms/NotionEditor/styles.css +478 -0
  131. package/src/tools/forms/NotionEditor/types.ts +28 -0
  132. package/src/tools/index.ts +153 -13
  133. package/src/tools/input/Combobox/lazy.tsx +1 -1
  134. package/src/tools/input/CronScheduler/components/CronPreview.README.md +28 -0
  135. package/src/tools/input/CronScheduler/components/CronPreview.tsx +136 -0
  136. package/src/tools/input/CronScheduler/components/index.ts +3 -0
  137. package/src/tools/input/CronScheduler/index.tsx +5 -1
  138. package/src/tools/input/CronScheduler/lazy.tsx +5 -1
  139. package/src/tools/input/CronScheduler/utils/cron-next-runs.ts +122 -0
  140. package/src/tools/input/CronScheduler/utils/index.ts +1 -0
  141. package/src/tools/input/Scroller/lazy.tsx +1 -1
  142. package/src/tools/input/Sortable/lazy.tsx +1 -1
  143. package/src/tools/input/SpeechRecognition/lazy.tsx +1 -1
  144. package/src/tools/input/SpeechRecognition/widgets/VoiceComposerSlot.tsx +41 -36
  145. package/src/tools/media/AudioPlayer/PlayerShell.tsx +3 -11
  146. package/src/tools/media/AudioPlayer/types.ts +4 -11
  147. package/src/tools/media/ImageViewer/components/ImageToolbar.tsx +58 -47
  148. package/src/tools/media/ImageViewer/components/ImageViewer.tsx +35 -19
  149. package/src/tools/media/ImageViewer/lazy.tsx +1 -1
  150. package/src/tools/media/ImageViewer/types.ts +4 -0
  151. package/src/tools/media/LottiePlayer/lazy.tsx +1 -1
  152. package/src/tools/media/VideoPlayer/VideoPlayer.tsx +47 -1
  153. package/src/tools/media/VideoPlayer/parts/fullscreen.tsx +21 -4
  154. package/src/tools/media/VideoPlayer/parts/pip.tsx +21 -4
  155. package/src/tools/media/VideoPlayer/parts/play-button.tsx +21 -4
  156. package/src/tools/media/VideoPlayer/parts/playback-rate.tsx +19 -3
  157. package/src/tools/media/VideoPlayer/parts/volume.tsx +237 -18
  158. package/src/tools/media/VideoPlayer/styles/video-player.css +87 -7
  159. package/src/tools/media/VideoPlayer/types.ts +4 -0
  160. package/src/tools/overlay/ResponsiveDialog/lazy.tsx +1 -1
  161. package/src/tools/overlay/ScrollSpy/lazy.tsx +1 -1
  162. package/src/tools/overlay/SelectionToolbar/lazy.tsx +1 -1
  163. package/src/tools/overlay/Tour/lazy.tsx +1 -1
  164. package/src/tools/visual/Marquee/lazy.tsx +1 -1
  165. package/src/tools/visual/QRCode/lazy.tsx +1 -1
  166. package/src/tools/visual/charts/ActivityGraph/ActivityGraph.tsx +195 -0
  167. package/src/tools/visual/charts/ActivityGraph/README.md +28 -0
  168. package/src/tools/visual/charts/ActivityGraph/index.ts +8 -0
  169. package/src/tools/visual/charts/ActivityGraph/lazy.tsx +21 -0
  170. package/src/tools/visual/charts/ActivityGraph/types.ts +59 -0
  171. package/src/tools/visual/charts/ActivityGraph/utils.ts +88 -0
  172. package/src/tools/visual/charts/CommitGraph/CommitGraph.tsx +80 -0
  173. package/src/tools/visual/charts/CommitGraph/README.md +28 -0
  174. package/src/tools/visual/charts/CommitGraph/components/CommitDetail.tsx +107 -0
  175. package/src/tools/visual/charts/CommitGraph/components/CommitRow.tsx +122 -0
  176. package/src/tools/visual/charts/CommitGraph/components/Rails.tsx +171 -0
  177. package/src/tools/visual/charts/CommitGraph/hooks/useGraphLayout.ts +169 -0
  178. package/src/tools/visual/charts/CommitGraph/hooks/useLaneColors.ts +45 -0
  179. package/src/tools/visual/charts/CommitGraph/index.ts +14 -0
  180. package/src/tools/visual/charts/CommitGraph/lazy.tsx +25 -0
  181. package/src/tools/visual/charts/CommitGraph/types.ts +85 -0
  182. package/src/tools/visual/charts/CommitGraph/utils.ts +53 -0
  183. package/src/tools/visual/{Gauge → charts/Gauge}/lazy.tsx +1 -1
  184. package/src/tools/visual/charts/Sparkline/README.md +29 -0
  185. package/src/tools/visual/charts/Sparkline/Sparkline.tsx +217 -0
  186. package/src/tools/visual/charts/Sparkline/index.ts +9 -0
  187. package/src/tools/visual/charts/Sparkline/lazy.tsx +26 -0
  188. package/src/tools/visual/charts/Sparkline/types.ts +58 -0
  189. package/src/tools/visual/design/ColorPalette/ColorPalette.tsx +129 -0
  190. package/src/tools/visual/design/ColorPalette/README.md +34 -0
  191. package/src/tools/visual/design/ColorPalette/components/Swatch.tsx +102 -0
  192. package/src/tools/visual/design/ColorPalette/hooks/useCopyToClipboard.ts +41 -0
  193. package/src/tools/visual/design/ColorPalette/index.ts +12 -0
  194. package/src/tools/visual/design/ColorPalette/lazy.tsx +21 -0
  195. package/src/tools/visual/design/ColorPalette/types.ts +63 -0
  196. package/src/tools/visual/design/ColorPalette/utils.ts +83 -0
  197. package/src/tools/visual/{ColorPicker → design/ColorPicker}/lazy.tsx +1 -1
  198. package/src/tools/visual/{FileIcon → design/FileIcon}/treeAdapter.tsx +1 -1
  199. package/src/tools/visual/{Fps → indicators/Fps}/lazy.tsx +1 -1
  200. package/src/tools/visual/{Rating → indicators/Rating}/lazy.tsx +1 -1
  201. package/src/tools/visual/indicators/StatusIndicator/README.md +28 -0
  202. package/src/tools/visual/indicators/StatusIndicator/StatusIndicator.tsx +83 -0
  203. package/src/tools/visual/indicators/StatusIndicator/index.ts +14 -0
  204. package/src/tools/visual/indicators/StatusIndicator/lazy.tsx +21 -0
  205. package/src/tools/visual/indicators/StatusIndicator/types.ts +133 -0
  206. package/src/components/FloatingToolbar/actions/CopyAction.tsx +0 -22
  207. package/src/components/FloatingToolbar/actions/ExpandAction.tsx +0 -25
  208. package/src/components/FloatingToolbar/actions/FullscreenAction.tsx +0 -30
  209. package/src/tools/data/JsonTree/components/JsonContent.tsx +0 -197
  210. package/src/tools/data/JsonTree/hooks/useJsonExpand.ts +0 -50
  211. /package/src/{components → common}/FloatingToolbar/FloatingToolbar.css +0 -0
  212. /package/src/{components → common}/FloatingToolbar/actions/index.ts +0 -0
  213. /package/src/{components → common}/FloatingToolbar/hooks/useElementCorner.ts +0 -0
  214. /package/src/{components → common}/FloatingToolbar/hooks/useScrollIsolation.ts +0 -0
  215. /package/src/{components → common}/index.ts +0 -0
  216. /package/src/{components → common}/lazy-wrapper.tsx +0 -0
  217. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/README.md +0 -0
  218. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/DocsView.tsx +0 -0
  219. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/LanguageTabs.tsx +0 -0
  220. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/useCodeSnippet.ts +0 -0
  221. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/MetaActions.tsx +0 -0
  222. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/MethodBadge.tsx +0 -0
  223. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/PathDisplay.tsx +0 -0
  224. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/ParamGroup.tsx +0 -0
  225. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/ParamRow.tsx +0 -0
  226. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/index.tsx +0 -0
  227. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/RequestBody/index.tsx +0 -0
  228. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/ResponseRow.tsx +0 -0
  229. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/StatusTag.tsx +0 -0
  230. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/index.tsx +0 -0
  231. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/FieldRow.tsx +0 -0
  232. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts +0 -0
  233. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/index.tsx +0 -0
  234. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/types.ts +0 -0
  235. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/SectionHeader.tsx +0 -0
  236. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/defaults.ts +0 -0
  237. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/index.tsx +0 -0
  238. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/context.tsx +0 -0
  239. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/hooks/useSectionHash.ts +0 -0
  240. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/index.tsx +0 -0
  241. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/store/index.ts +0 -0
  242. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/store/selectors.ts +0 -0
  243. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/types.ts +0 -0
  244. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/SchemaCopyMenu.tsx +0 -0
  245. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/BrandHeader.tsx +0 -0
  246. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/CategoryBlock.tsx +0 -0
  247. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/EndpointRow.tsx +0 -0
  248. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SchemaSection.tsx +0 -0
  249. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SearchInput.tsx +0 -0
  250. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SidebarBody.tsx +0 -0
  251. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/Toolbar.tsx +0 -0
  252. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/buildVM.ts +0 -0
  253. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/index.tsx +0 -0
  254. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/types.ts +0 -0
  255. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/useDebouncedValue.ts +0 -0
  256. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/SlideInPlayground.tsx +0 -0
  257. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/TryItSheet.tsx +0 -0
  258. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/anchor.ts +0 -0
  259. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/grouping.ts +0 -0
  260. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/index.tsx +0 -0
  261. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/sidebarLabel.ts +0 -0
  262. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/index.ts +0 -0
  263. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/BodyFormEditor.tsx +0 -0
  264. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/EndpointDraftSync.tsx +0 -0
  265. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/EndpointResetButton.tsx +0 -0
  266. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/PreviewView.tsx +0 -0
  267. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/RawView.tsx +0 -0
  268. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/StatusBar.tsx +0 -0
  269. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/ViewTabs.tsx +0 -0
  270. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/detectContent.ts +0 -0
  271. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/index.tsx +0 -0
  272. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/useResponseView.ts +0 -0
  273. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/SendButton.tsx +0 -0
  274. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ui.tsx +0 -0
  275. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/constants.ts +0 -0
  276. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/context/PlaygroundContext.tsx +0 -0
  277. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/index.ts +0 -0
  278. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useDocsUrlSync.ts +0 -0
  279. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useEndpointDraft.ts +0 -0
  280. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useMobile.ts +0 -0
  281. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useOpenApiSchema.ts +0 -0
  282. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/index.tsx +0 -0
  283. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/types.ts +0 -0
  284. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/apiKeyManager.ts +0 -0
  285. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/codeSamples.ts +0 -0
  286. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/formatters.ts +0 -0
  287. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/index.ts +0 -0
  288. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/operationToHar.ts +0 -0
  289. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/sampler.ts +0 -0
  290. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/schemaExport.ts +0 -0
  291. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/scrollParent.ts +0 -0
  292. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/url.ts +0 -0
  293. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/versionManager.ts +0 -0
  294. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/ActionRow.tsx +0 -0
  295. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/ChatMessageRow.tsx +0 -0
  296. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/CodeBlock.tsx +0 -0
  297. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/README.md +0 -0
  298. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/index.ts +0 -0
  299. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/linkRules.ts +0 -0
  300. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/plainText.ts +0 -0
  301. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/sanitize.ts +0 -0
  302. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/types.ts +0 -0
  303. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/README.md +0 -0
  304. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/index.tsx +0 -0
  305. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/registerPrismLanguages.ts +0 -0
  306. /package/src/tools/visual/{Gauge → charts/Gauge}/Gauge.tsx +0 -0
  307. /package/src/tools/visual/{Gauge → charts/Gauge}/index.ts +0 -0
  308. /package/src/tools/visual/{Gauge → charts/Gauge}/types.ts +0 -0
  309. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/ColorPicker.tsx +0 -0
  310. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/ColorPickerContext.tsx +0 -0
  311. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/ColorPickerStore.tsx +0 -0
  312. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/index.ts +0 -0
  313. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/index.ts +0 -0
  314. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/lib/color-utils.ts +0 -0
  315. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerAlphaSlider.tsx +0 -0
  316. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerArea.tsx +0 -0
  317. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerEyeDropper.tsx +0 -0
  318. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerFormatSelect.tsx +0 -0
  319. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerHueSlider.tsx +0 -0
  320. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerInput.tsx +0 -0
  321. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerSwatch.tsx +0 -0
  322. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/index.ts +0 -0
  323. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/types.ts +0 -0
  324. /package/src/tools/visual/{FileIcon → design/FileIcon}/FileIcon.tsx +0 -0
  325. /package/src/tools/visual/{FileIcon → design/FileIcon}/get-file-icon.ts +0 -0
  326. /package/src/tools/visual/{FileIcon → design/FileIcon}/icons/icon-data.ts +0 -0
  327. /package/src/tools/visual/{FileIcon → design/FileIcon}/index.ts +0 -0
  328. /package/src/tools/visual/{FileIcon → design/FileIcon}/loader.ts +0 -0
  329. /package/src/tools/visual/{FileIcon → design/FileIcon}/specialFolders.ts +0 -0
  330. /package/src/tools/visual/{Fps → indicators/Fps}/Fps.tsx +0 -0
  331. /package/src/tools/visual/{Fps → indicators/Fps}/index.ts +0 -0
  332. /package/src/tools/visual/{Fps → indicators/Fps}/types.ts +0 -0
  333. /package/src/tools/visual/{Rating → indicators/Rating}/Rating.tsx +0 -0
  334. /package/src/tools/visual/{Rating → indicators/Rating}/index.ts +0 -0
  335. /package/src/tools/visual/{Rating → indicators/Rating}/types.ts +0 -0
@@ -0,0 +1,8 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ export { ActivityGraph } from './ActivityGraph';
4
+ export {
5
+ DEFAULT_INTENSITY_OPACITY,
6
+ DEFAULT_INTENSITY_THRESHOLDS,
7
+ } from './types';
8
+ export type { ActivityGraphProps, ActivityEntry } from './types';
@@ -0,0 +1,21 @@
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 { ActivityGraphProps } from './types';
7
+
8
+ export const LazyActivityGraph = createLazyComponent<ActivityGraphProps>(
9
+ () => import('./ActivityGraph').then((mod) => ({ default: mod.ActivityGraph })),
10
+ {
11
+ displayName: 'LazyActivityGraph',
12
+ fallback: (
13
+ <div
14
+ data-slot="activity-graph-skeleton"
15
+ className="h-[120px] w-full animate-pulse rounded-md bg-muted"
16
+ />
17
+ ),
18
+ },
19
+ );
20
+
21
+ export type { ActivityGraphProps, ActivityEntry } from './types';
@@ -0,0 +1,59 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ import type * as React from 'react';
4
+
5
+ /**
6
+ * Single day entry in the contribution heatmap.
7
+ */
8
+ export interface ActivityEntry {
9
+ /** ISO date string (YYYY-MM-DD). */
10
+ date: string;
11
+ /** Activity count for this date. */
12
+ count: number;
13
+ }
14
+
15
+ /**
16
+ * Five opacity stops applied to the resolved theme `primary` color for
17
+ * intensity levels 0–4. Level 0 is the empty / no-activity surface and is
18
+ * intentionally low (almost equal to `bg-muted`).
19
+ *
20
+ * Audit notes (AUDIT.md §1) collapse the full emerald scale to
21
+ * `alpha(primary, …)`, so the same five stops cover light and dark themes.
22
+ */
23
+ export const DEFAULT_INTENSITY_OPACITY: readonly [number, number, number, number, number] = [
24
+ 0.08, 0.18, 0.35, 0.6, 0.95,
25
+ ] as const;
26
+
27
+ /**
28
+ * Thresholds (ratios of `value / max`) that map a normalized count into
29
+ * one of four non-zero intensity buckets. Combined with the empty bucket
30
+ * for `count === 0` they yield the 5 levels expected by the heatmap.
31
+ *
32
+ * Mirrors the original jalcoui `getIntensity` (`<=0.25 / 0.5 / 0.75`).
33
+ */
34
+ export const DEFAULT_INTENSITY_THRESHOLDS: readonly [number, number, number] = [0.25, 0.5, 0.75];
35
+
36
+ export interface ActivityGraphProps extends Omit<React.ComponentProps<'div'>, 'children'> {
37
+ /** Activity data entries. Duplicates with the same `date` are summed. */
38
+ data: ActivityEntry[];
39
+ /**
40
+ * Override the 5 opacity stops applied to the active theme `primary`
41
+ * color. Index 0 is the empty surface; index 4 is the peak.
42
+ */
43
+ intensityOpacity?: readonly [number, number, number, number, number];
44
+ /**
45
+ * Fixed cell size in pixels. When omitted the component auto-sizes
46
+ * blocks to fill the available container width via `useResizeObserver`.
47
+ */
48
+ blockSize?: number;
49
+ /** Cell border radius in pixels. @default 2 */
50
+ blockRadius?: number;
51
+ /** Number of trailing weeks to display. @default 52 */
52
+ weeks?: number;
53
+ }
54
+
55
+ export const GAP = 2;
56
+ export const DAY_LABEL_WIDTH = 28;
57
+ export const MONTH_LABEL_HEIGHT = 16;
58
+ export const DAY_LABELS = ['Mon', 'Wed', 'Fri'] as const;
59
+ export const DAY_LABEL_INDICES = [1, 3, 5] as const;
@@ -0,0 +1,88 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ import type { ActivityEntry } from './types';
4
+ import { GAP } from './types';
5
+
6
+ export interface WeekDay {
7
+ date: Date;
8
+ count: number;
9
+ }
10
+
11
+ /**
12
+ * Bucket the supplied entries into a fixed-size grid that ends on the
13
+ * current week and spans `weekCount` weeks. Missing dates fill with 0.
14
+ */
15
+ export function buildWeeks(data: ActivityEntry[], weekCount: number): WeekDay[][] {
16
+ const countMap = new Map<string, number>();
17
+ for (const entry of data) {
18
+ countMap.set(entry.date, (countMap.get(entry.date) ?? 0) + entry.count);
19
+ }
20
+
21
+ const today = new Date();
22
+ today.setHours(0, 0, 0, 0);
23
+ const todayDay = today.getDay();
24
+
25
+ const endOfWeek = new Date(today);
26
+ endOfWeek.setDate(today.getDate() + (6 - todayDay));
27
+
28
+ const totalDays = weekCount * 7;
29
+ const startDate = new Date(endOfWeek);
30
+ startDate.setDate(endOfWeek.getDate() - totalDays + 1);
31
+
32
+ const weeks: WeekDay[][] = [];
33
+ let currentWeek: WeekDay[] = [];
34
+
35
+ for (let i = 0; i < totalDays; i++) {
36
+ const d = new Date(startDate);
37
+ d.setDate(startDate.getDate() + i);
38
+ const key = d.toISOString().slice(0, 10);
39
+ currentWeek.push({ date: d, count: countMap.get(key) ?? 0 });
40
+
41
+ if (currentWeek.length === 7) {
42
+ weeks.push(currentWeek);
43
+ currentWeek = [];
44
+ }
45
+ }
46
+
47
+ if (currentWeek.length > 0) {
48
+ weeks.push(currentWeek);
49
+ }
50
+
51
+ return weeks;
52
+ }
53
+
54
+ /**
55
+ * Find the column offset for the first week of every new month. Used to
56
+ * lay month labels along the top of the grid.
57
+ */
58
+ export function getMonthLabels(
59
+ weeks: WeekDay[][],
60
+ blockSize: number,
61
+ ): { label: string; offset: number }[] {
62
+ const months: { label: string; offset: number }[] = [];
63
+ let lastKey = '';
64
+
65
+ for (let w = 0; w < weeks.length; w++) {
66
+ const firstDay = weeks[w][0];
67
+ const key = `${firstDay.date.getFullYear()}-${firstDay.date.getMonth()}`;
68
+
69
+ if (key !== lastKey) {
70
+ months.push({
71
+ label: firstDay.date.toLocaleString('en-US', { month: 'short' }),
72
+ offset: w * (blockSize + GAP),
73
+ });
74
+ lastKey = key;
75
+ }
76
+ }
77
+
78
+ return months;
79
+ }
80
+
81
+ export function formatDate(date: Date): string {
82
+ return date.toLocaleDateString('en-US', {
83
+ weekday: 'short',
84
+ month: 'short',
85
+ day: 'numeric',
86
+ year: 'numeric',
87
+ });
88
+ }
@@ -0,0 +1,80 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+ //
3
+ // Topological git graph with rail lines showing branch forks, merges, and
4
+ // commit ancestry. Renders the same visual as GitKraken / Fork / Tower.
5
+ //
6
+ // Composer only — heavy lifting lives in:
7
+ // - hooks/useGraphLayout.ts topology pass
8
+ // - hooks/useLaneColors.ts theme-aware categorical palette
9
+ // - components/Rails.tsx SVG rails + dot
10
+ // - components/CommitRow.tsx row body (refs, message, meta)
11
+ // - components/CommitDetail.tsx popover detail
12
+ //
13
+ // Project rules exercised here: semantic tokens for chrome (no raw scales),
14
+ // theme-derived hex colors for SVG strokes (no Tailwind classes inside
15
+ // `stroke=`), no nested overlay providers, attribution header, lazy entry.
16
+
17
+ 'use client';
18
+
19
+ import * as React from 'react';
20
+ import { cn } from '@djangocfg/ui-core/lib';
21
+ import type { CommitGraphProps } from './types';
22
+ import { useGraphLayout } from './hooks/useGraphLayout';
23
+ import { useLaneColors, pickLaneColor } from './hooks/useLaneColors';
24
+ import { CommitRow } from './components/CommitRow';
25
+
26
+ function CommitGraph({
27
+ commits,
28
+ truncateHash = 7,
29
+ railWidth = 24,
30
+ className,
31
+ ...props
32
+ }: CommitGraphProps) {
33
+ const laneColors = useLaneColors();
34
+ const { rows, maxRails } = useGraphLayout(commits, laneColors);
35
+ const svgWidth = maxRails * railWidth;
36
+
37
+ if (rows.length === 0) {
38
+ return (
39
+ <div
40
+ data-slot="commit-graph"
41
+ className={cn(
42
+ 'flex items-center justify-center rounded-xl border border-border/60 bg-card py-10 text-sm text-muted-foreground shadow-sm',
43
+ className,
44
+ )}
45
+ {...props}
46
+ >
47
+ No commits.
48
+ </div>
49
+ );
50
+ }
51
+
52
+ return (
53
+ <div
54
+ data-slot="commit-graph"
55
+ className={cn(
56
+ 'overflow-hidden rounded-xl border border-border/60 bg-card shadow-sm',
57
+ className,
58
+ )}
59
+ style={{ ['--commit-graph-rail-width' as string]: `${svgWidth}px` }}
60
+ {...props}
61
+ >
62
+ <div className="overflow-x-auto">
63
+ {rows.map((row, i) => (
64
+ <CommitRow
65
+ key={`${row.commit.hash}-${i}`}
66
+ row={row}
67
+ prevRow={i > 0 ? rows[i - 1] : null}
68
+ railWidth={railWidth}
69
+ maxRails={maxRails}
70
+ truncateHash={truncateHash}
71
+ laneColors={laneColors}
72
+ railColor={pickLaneColor(laneColors, row.rail)}
73
+ />
74
+ ))}
75
+ </div>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ export { CommitGraph };
@@ -0,0 +1,28 @@
1
+ # CommitGraph
2
+
3
+ Git-style commit rail visualisation. Computes rail topology from `parents` and renders SVG rails + edges. Lane colors come from `useStylePresets()` so every theme preset re-skins consistently.
4
+
5
+ ```tsx
6
+ import { CommitGraph } from '@djangocfg/ui-tools/commit-graph';
7
+
8
+ <CommitGraph
9
+ commits={[
10
+ { hash: 'a1b2c3d', message: 'init', author: { name: 'Mark' }, date: '2025-01-01', parents: [] },
11
+ { hash: 'd4e5f6g', message: 'feat: auth', author: { name: 'Mark' }, date: '2025-01-02', parents: ['a1b2c3d'] },
12
+ ]}
13
+ />
14
+ ```
15
+
16
+ ## Props
17
+
18
+ | Prop | Type | Default | Description |
19
+ |---|---|---|---|
20
+ | `commits` | `Commit[]` | — | Commits in topological order (newest first). Merge = two+ `parents`. |
21
+ | `truncateHash` | `number` | `7` | Number of hash characters to display. |
22
+ | `railWidth` | `number` | `24` | Pixel width per rail column. |
23
+
24
+ Storybook: `apps/storybook/stories/ui-tools/visual/CommitGraph.stories.tsx`
25
+
26
+ ---
27
+
28
+ Adapted from jalcoui (MIT).
@@ -0,0 +1,107 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ /* eslint-disable @next/next/no-img-element */
6
+
7
+ import * as React from 'react';
8
+ import { Popover, PopoverContent, PopoverTrigger } from '@djangocfg/ui-core';
9
+ import { alpha } from '@djangocfg/ui-core/styles/palette';
10
+ import type { Commit } from '../types';
11
+ import { formatFullDate, initials } from '../utils';
12
+
13
+ interface CommitDetailProps {
14
+ commit: Commit;
15
+ hashLength: number;
16
+ railColor: string;
17
+ children: React.ReactNode;
18
+ }
19
+
20
+ /**
21
+ * Popover with the full commit message, refs, tag and parent hashes. The
22
+ * trigger is the row button — the parent component owns the row markup and
23
+ * passes it through `children`.
24
+ *
25
+ * Requires the host app to mount `<UiProviders>` at the root (we do not
26
+ * remount a Popover provider here — see CONTRACT §5).
27
+ */
28
+ export function CommitDetail({
29
+ commit,
30
+ hashLength,
31
+ railColor,
32
+ children,
33
+ }: CommitDetailProps) {
34
+ // Pre-compute style strings outside JSX (per project rule: hoist derived
35
+ // values into named consts before `return (...)`).
36
+ const tagStyle = {
37
+ backgroundColor: alpha(railColor, 0.125),
38
+ color: railColor,
39
+ };
40
+ const initialsLabel = initials(commit.author.name);
41
+
42
+ return (
43
+ <Popover>
44
+ <PopoverTrigger asChild>{children}</PopoverTrigger>
45
+ <PopoverContent side="right" sideOffset={8} className="w-80 p-3">
46
+ <div className="flex flex-col gap-2">
47
+ <p className="text-sm font-medium leading-snug">{commit.message}</p>
48
+
49
+ <div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
50
+ <span className="inline-flex items-center gap-1.5">
51
+ {commit.author.avatarUrl ? (
52
+ <img
53
+ src={commit.author.avatarUrl}
54
+ alt=""
55
+ width={14}
56
+ height={14}
57
+ className="size-3.5 rounded-full border border-border/60 bg-muted"
58
+ />
59
+ ) : (
60
+ <span className="flex size-3.5 items-center justify-center rounded-full bg-muted text-[7px] font-bold">
61
+ {initialsLabel}
62
+ </span>
63
+ )}
64
+ {commit.author.name}
65
+ </span>
66
+ <span className="text-border">·</span>
67
+ <code className="rounded bg-muted px-1 py-0.5 font-mono text-[10px]">
68
+ {commit.hash.slice(0, hashLength)}
69
+ </code>
70
+ </div>
71
+
72
+ <div className="text-[11px] text-muted-foreground">
73
+ {formatFullDate(commit.date)}
74
+ </div>
75
+
76
+ {(commit.refs || commit.tag) && (
77
+ <div className="flex flex-wrap gap-1">
78
+ {commit.refs?.map((ref) => (
79
+ <span
80
+ key={ref}
81
+ className="inline-flex items-center gap-1 rounded-md border border-border/60 bg-muted/50 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground"
82
+ >
83
+ {ref}
84
+ </span>
85
+ ))}
86
+ {commit.tag && (
87
+ <span
88
+ className="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-medium"
89
+ style={tagStyle}
90
+ >
91
+ {commit.tag}
92
+ </span>
93
+ )}
94
+ </div>
95
+ )}
96
+
97
+ {commit.parents.length > 0 && (
98
+ <div className="text-[10px] text-muted-foreground/60">
99
+ {commit.parents.length === 1 ? 'Parent' : 'Parents'}:{' '}
100
+ {commit.parents.map((p) => p.slice(0, hashLength)).join(', ')}
101
+ </div>
102
+ )}
103
+ </div>
104
+ </PopoverContent>
105
+ </Popover>
106
+ );
107
+ }
@@ -0,0 +1,122 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ /* eslint-disable @next/next/no-img-element */
6
+
7
+ import * as React from 'react';
8
+ import { alpha } from '@djangocfg/ui-core/styles/palette';
9
+ import { ROW_HEIGHT, type GraphRow } from '../types';
10
+ import { formatRelativeDate, initials } from '../utils';
11
+ import { CommitDetail } from './CommitDetail';
12
+ import { Rails } from './Rails';
13
+
14
+ interface CommitRowProps {
15
+ row: GraphRow;
16
+ prevRow: GraphRow | null;
17
+ railWidth: number;
18
+ maxRails: number;
19
+ truncateHash: number;
20
+ laneColors: string[];
21
+ railColor: string;
22
+ }
23
+
24
+ /**
25
+ * Single commit row: rails column, refs, message, hash + author + time.
26
+ * Wrapped in a {@link CommitDetail} popover.
27
+ */
28
+ export function CommitRow({
29
+ row,
30
+ prevRow,
31
+ railWidth,
32
+ maxRails,
33
+ truncateHash,
34
+ laneColors,
35
+ railColor,
36
+ }: CommitRowProps) {
37
+ const svgWidth = maxRails * railWidth;
38
+ const refStyle = {
39
+ borderColor: alpha(railColor, 0.25),
40
+ backgroundColor: alpha(railColor, 0.0625),
41
+ color: railColor,
42
+ };
43
+ const tagStyle = {
44
+ backgroundColor: alpha(railColor, 0.125),
45
+ color: railColor,
46
+ };
47
+ const initialsLabel = initials(row.commit.author.name);
48
+ const shortHash = row.commit.hash.slice(0, truncateHash);
49
+ const relativeDate = formatRelativeDate(row.commit.date);
50
+
51
+ return (
52
+ <CommitDetail commit={row.commit} hashLength={truncateHash} railColor={railColor}>
53
+ <button
54
+ type="button"
55
+ data-slot="commit-entry"
56
+ className="flex w-full items-center gap-0 border-b border-border/30 transition-colors hover:bg-muted/30 focus-visible:bg-muted/30 focus-visible:outline-none last:border-b-0"
57
+ style={{ height: ROW_HEIGHT }}
58
+ >
59
+ {/* Rails */}
60
+ <div style={{ width: svgWidth }} className="shrink-0">
61
+ <Rails
62
+ row={row}
63
+ prevRow={prevRow}
64
+ railWidth={railWidth}
65
+ maxRails={maxRails}
66
+ laneColors={laneColors}
67
+ />
68
+ </div>
69
+
70
+ {/* Refs + tag */}
71
+ <div className="flex shrink-0 items-center gap-1 px-2">
72
+ {row.commit.refs?.map((ref) => (
73
+ <span
74
+ key={ref}
75
+ className="inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-[10px] font-semibold leading-none"
76
+ style={refStyle}
77
+ >
78
+ {ref}
79
+ </span>
80
+ ))}
81
+ {row.commit.tag && (
82
+ <span
83
+ className="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-semibold leading-none"
84
+ style={tagStyle}
85
+ >
86
+ {row.commit.tag}
87
+ </span>
88
+ )}
89
+ </div>
90
+
91
+ {/* Message */}
92
+ <p className="min-w-0 flex-1 truncate px-2 text-left text-sm text-foreground/80">
93
+ {row.commit.message}
94
+ </p>
95
+
96
+ {/* Meta */}
97
+ <div className="flex shrink-0 items-center gap-3 px-3">
98
+ <code className="font-mono text-[11px] text-muted-foreground/60">
99
+ {shortHash}
100
+ </code>
101
+ <span className="inline-flex items-center gap-1.5 text-xs text-muted-foreground">
102
+ {row.commit.author.avatarUrl ? (
103
+ <img
104
+ src={row.commit.author.avatarUrl}
105
+ alt=""
106
+ width={16}
107
+ height={16}
108
+ className="size-4 rounded-full border border-border/60 bg-muted"
109
+ />
110
+ ) : (
111
+ <span className="flex size-4 items-center justify-center rounded-full bg-muted text-[8px] font-bold text-muted-foreground">
112
+ {initialsLabel}
113
+ </span>
114
+ )}
115
+ <span className="hidden sm:inline">{row.commit.author.name}</span>
116
+ </span>
117
+ <span className="text-[11px] text-muted-foreground/50">{relativeDate}</span>
118
+ </div>
119
+ </button>
120
+ </CommitDetail>
121
+ );
122
+ }
@@ -0,0 +1,171 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import * as React from 'react';
6
+ import { useThemeColor } from '@djangocfg/ui-core/styles/palette';
7
+ import { ROW_HEIGHT, type GraphRow } from '../types';
8
+ import { pickLaneColor } from '../hooks/useLaneColors';
9
+
10
+ interface RailsProps {
11
+ row: GraphRow;
12
+ prevRow: GraphRow | null;
13
+ railWidth: number;
14
+ maxRails: number;
15
+ laneColors: string[];
16
+ }
17
+
18
+ /**
19
+ * SVG renderer for the rail column of a single commit row.
20
+ *
21
+ * Draws four classes of geometry:
22
+ * 1. Pass-through rails — straight vertical line top→bottom for any rail
23
+ * that is active above *and* below this row and is not the commit rail.
24
+ * 2. Commit rail incoming/outgoing — half-height verticals on the commit's
25
+ * own rail, depending on whether the rail was active above/below.
26
+ * 3. Fork-out curves — bezier from the commit's rail down to a freshly
27
+ * allocated rail (a new branch coming off this commit).
28
+ * 4. Merge curves — bezier from a source rail into the commit dot
29
+ * (or from the dot down to a target rail).
30
+ *
31
+ * SVG fill/stroke values are hex strings resolved via the theme palette;
32
+ * raw Tailwind classes do not work inside `stroke=`.
33
+ */
34
+ export function Rails({ row, prevRow, railWidth, maxRails, laneColors }: RailsProps) {
35
+ // Background color for the commit dot ring — matches the surface the row
36
+ // is mounted on so the dot reads as "popped out" on every preset.
37
+ const background = useThemeColor('background');
38
+
39
+ const w = maxRails * railWidth;
40
+ const h = ROW_HEIGHT;
41
+ const cy = h / 2;
42
+ const rx = (rail: number) => rail * railWidth + railWidth / 2;
43
+ const color = (rail: number) => pickLaneColor(laneColors, rail);
44
+
45
+ const commitX = rx(row.rail);
46
+
47
+ const activeAbove = new Set<number>();
48
+ if (prevRow) {
49
+ for (let r = 0; r < prevRow.rails.length; r++) {
50
+ if (prevRow.rails[r] !== null) activeAbove.add(r);
51
+ }
52
+ }
53
+ const activeBelow = new Set<number>();
54
+ for (let r = 0; r < row.rails.length; r++) {
55
+ if (row.rails[r] !== null) activeBelow.add(r);
56
+ }
57
+
58
+ const passThroughRails = Array.from(activeAbove).filter(
59
+ (r) => r !== row.rail && activeBelow.has(r),
60
+ );
61
+ const endingRails = Array.from(activeAbove).filter(
62
+ (r) => r !== row.rail && !activeBelow.has(r),
63
+ );
64
+ const forkEdges = row.edges.filter((e) => e.type === 'fork-out');
65
+ const mergeEdges = row.edges.filter((e) => e.type === 'merge-in');
66
+
67
+ return (
68
+ <svg
69
+ width={w}
70
+ height={h}
71
+ viewBox={`0 0 ${w} ${h}`}
72
+ className="shrink-0"
73
+ aria-hidden="true"
74
+ >
75
+ {passThroughRails.map((r) => {
76
+ const x = rx(r);
77
+ return (
78
+ <line
79
+ key={`pt-${r}`}
80
+ x1={x}
81
+ y1={0}
82
+ x2={x}
83
+ y2={h}
84
+ stroke={color(r)}
85
+ strokeWidth={2}
86
+ strokeOpacity={0.6}
87
+ />
88
+ );
89
+ })}
90
+
91
+ {activeAbove.has(row.rail) && (
92
+ <line
93
+ x1={commitX}
94
+ y1={0}
95
+ x2={commitX}
96
+ y2={cy}
97
+ stroke={color(row.rail)}
98
+ strokeWidth={2}
99
+ strokeOpacity={0.6}
100
+ />
101
+ )}
102
+
103
+ {activeBelow.has(row.rail) && (
104
+ <line
105
+ x1={commitX}
106
+ y1={cy}
107
+ x2={commitX}
108
+ y2={h}
109
+ stroke={color(row.rail)}
110
+ strokeWidth={2}
111
+ strokeOpacity={0.6}
112
+ />
113
+ )}
114
+
115
+ {forkEdges.map((edge, i) => (
116
+ <path
117
+ key={`f-${i}`}
118
+ d={`M${rx(edge.fromRail)},${cy} C${rx(edge.fromRail)},${h} ${rx(edge.toRail)},${cy} ${rx(edge.toRail)},${h}`}
119
+ stroke={edge.color}
120
+ strokeWidth={2}
121
+ strokeOpacity={0.6}
122
+ fill="none"
123
+ />
124
+ ))}
125
+
126
+ {mergeEdges.map((edge, i) => {
127
+ const isOutgoing = edge.fromRail === row.rail;
128
+ const x1 = rx(edge.fromRail);
129
+ const x2 = rx(edge.toRail);
130
+ const d = isOutgoing
131
+ ? `M${x1},${cy} C${x1},${h} ${x2},${cy} ${x2},${h}`
132
+ : `M${x1},${0} C${x1},${cy} ${x2},${0} ${x2},${cy}`;
133
+ return (
134
+ <path
135
+ key={`m-${i}`}
136
+ d={d}
137
+ stroke={edge.color}
138
+ strokeWidth={2}
139
+ strokeOpacity={0.6}
140
+ fill="none"
141
+ />
142
+ );
143
+ })}
144
+
145
+ {endingRails.map((r) => {
146
+ const x = rx(r);
147
+ return (
148
+ <line
149
+ key={`end-${r}`}
150
+ x1={x}
151
+ y1={0}
152
+ x2={x}
153
+ y2={cy}
154
+ stroke={color(r)}
155
+ strokeWidth={2}
156
+ strokeOpacity={0.6}
157
+ />
158
+ );
159
+ })}
160
+
161
+ <circle
162
+ cx={commitX}
163
+ cy={cy}
164
+ r={5}
165
+ fill={color(row.rail)}
166
+ stroke={background}
167
+ strokeWidth={2}
168
+ />
169
+ </svg>
170
+ );
171
+ }