@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,237 @@
1
+ # NotionEditor
2
+
3
+ Notion-style WYSIWYG markdown editor built on **TipTap v3**.
4
+
5
+ Lazy-loaded sibling of [`MarkdownEditor`](../MarkdownEditor/) — same
6
+ markdown round-trip, but with a heavier extension stack and the
7
+ floating menus (slash / bubble / drag handle) that users expect from a
8
+ "document" editor.
9
+
10
+ ```tsx
11
+ import { NotionEditor } from '@djangocfg/ui-tools/notion-editor';
12
+
13
+ <NotionEditor
14
+ value={markdown}
15
+ onChange={setMarkdown}
16
+ onSave={(md) => writeFile(md)}
17
+ autoFocus
18
+ placeholder="Type '/' for commands…"
19
+ />
20
+ ```
21
+
22
+ ## When to use this vs `MarkdownEditor`
23
+
24
+ | Use case | Pick |
25
+ | --------------------------------------- | ------------------- |
26
+ | Chat composer, single-paragraph input | `MarkdownEditor` |
27
+ | Note / doc surface, multi-paragraph | `NotionEditor` |
28
+ | `.md` file viewer with full editing | `NotionEditor` |
29
+ | Slim mention dropdown, no tables/tasks | `MarkdownEditor` |
30
+ | Slash menu, drag handle, tables, hljs | `NotionEditor` |
31
+
32
+ The two coexist intentionally — `NotionEditor` is ~350 KB minified
33
+ (lowlight common pack + tables + drag handle); `MarkdownEditor` is
34
+ ~200 KB. Don't mount NotionEditor inside a chat composer just to get
35
+ features the user will never use.
36
+
37
+ ## Features
38
+
39
+ - **Slash menu (`/`)** — 11 commands: Text, H1-H3, Bullet/Numbered/Todo
40
+ lists, Quote, Code block, Divider, Table. Each item shows its
41
+ markdown shorthand (`#`, `- [ ]`, etc.) as a kbd hint. Filtering by
42
+ title + aliases. `Esc` / click-outside close.
43
+ - **Bubble menu** — floating selection toolbar with Bold, Italic,
44
+ Underline, Strike, Code, Highlight, Link. Each button has a Tooltip
45
+ with the keyboard shortcut. Auto-hides inside code blocks and on
46
+ empty selections.
47
+ - **Cmd+K link prompt** — opens a Radix Dialog with URL input and
48
+ Save/Remove/Cancel. Snapshots and restores selection across the
49
+ dialog mount. Rejects unsafe schemes (`javascript:`, `data:`).
50
+ - **Drag handle** — Notion-style ⠿ grip appears on the left of every
51
+ block on hover (powered by `tiptap-extension-global-drag-handle`).
52
+ The icon is rendered as a `mask-image` of `lucide`'s `GripVertical`
53
+ so it matches the rest of the app at the pixel level.
54
+ - **Smart Cmd+A** — first press selects the current text block, second
55
+ press selects the whole document (Notion convention).
56
+ - **Heading-aware placeholder** — empty H1/H2/H3 show "Heading 1/2/3";
57
+ empty paragraphs show the supplied placeholder.
58
+ - **Forced-dark code blocks** — code blocks render on a fixed One Dark
59
+ Pro surface regardless of host theme. Avoids the washed-out
60
+ "light syntax on light page" look every editor hits.
61
+ - **Task list with ui-core `<Checkbox>`** — `taskItem` uses a React
62
+ `NodeView` so the checkbox is the same component used everywhere
63
+ else in the app (theme-aware, focus ring, etc.). Aligned to the
64
+ text cap-height via `align-items: baseline`.
65
+ - **Cmd+S save hook** — `onSave?: (md: string) => void` bound to
66
+ Cmd/Ctrl+S via `useHotkey`, scoped to the editor DOM so it doesn't
67
+ collide with global palettes higher up.
68
+ - **autoFocus** — declarative prop. Pair with `key={path}` upstream
69
+ when the parent wants a fresh focus per file change.
70
+ - **Markdown shortcuts** — StarterKit's input rules cover `#`, `>`,
71
+ `-`, `1.`, `` ``` ``, `---` → matching block on type.
72
+
73
+ ## Extension stack
74
+
75
+ Built once per editor instance (see `extensions.ts`). Order matters
76
+ for markdown serialisation — `Markdown` is registered before
77
+ `Highlight`/`TaskList` so the latter use the markdown extension's
78
+ node spec when serialising.
79
+
80
+ - `StarterKit` — paragraph, headings 1-4, bold/italic/code/strike,
81
+ blockquote, ordered+unordered list, link, underline, horizontal
82
+ rule, history. CodeBlock is **disabled** here — replaced by
83
+ `CodeBlockLowlight` for syntax highlighting.
84
+ - `Placeholder` — heading-aware ghost text.
85
+ - `Markdown` — bidirectional serialisation via `@tiptap/markdown`.
86
+ Handles tables, task lists (`- [ ]`), highlight (`==text==`).
87
+ - `Highlight` — `==text==` mark.
88
+ - `TaskList` + `TaskItem.extend({ addNodeView: TaskItemView })`.
89
+ - `Table` + `TableRow` + `TableHeader` + `TableCell`.
90
+ - `CodeBlockLowlight` — uses `lowlight`'s `common` language pack
91
+ (~25 languages). Add more by importing them and registering on the
92
+ shared `lowlight` instance.
93
+ - `GlobalDragHandle` — block grabber. **One handle per page** — see
94
+ the "Known limitations" section below.
95
+ - `SlashExtension` — wraps `@tiptap/suggestion` for the `/` menu.
96
+ - `CustomKeymap` — smart Cmd+A.
97
+
98
+ ## Files
99
+
100
+ | File | Purpose |
101
+ | ----------------------------- | ----------------------------------------------------------- |
102
+ | `lazy.tsx` | Subpath entry — `React.lazy` + `forwardRef` for the handle |
103
+ | `NotionEditor.tsx` | Main component + `BubbleSelectionToolbar` |
104
+ | `extensions.ts` | Assembled TipTap stack (factory `notionExtensions()`) |
105
+ | `types.ts` | `NotionEditorProps`, `NotionEditorHandle` |
106
+ | `SlashExtension.ts` | TipTap extension wrapping `@tiptap/suggestion` |
107
+ | `createSlashSuggestion.ts` | Suggestion config — floating-ui popup mount/update/teardown |
108
+ | `SlashList.tsx` | Popover content (listbox + keyboard nav) |
109
+ | `slashItems.ts` | Command list + `filterSlashItems` helper |
110
+ | `CustomKeymap.ts` | Smart Cmd+A extension |
111
+ | `TaskItemView.tsx` | React NodeView for `taskItem` (mounts ui-core Checkbox) |
112
+ | `LinkDialog.tsx` | Cmd+K link prompt (ui-core Dialog) |
113
+ | `styles.css` | Typography + slash/bubble menu + drag handle + lowlight |
114
+
115
+ ## Imperative API
116
+
117
+ ```tsx
118
+ const ref = useRef<NotionEditorHandle>(null);
119
+
120
+ ref.current?.focus(); // focus the editor surface
121
+ ref.current?.moveCursorToEnd(); // focus + caret at end
122
+ ref.current?.getEditor(); // raw TipTap Editor (escape hatch)
123
+ ```
124
+
125
+ `NotionEditorHandle` is structurally compatible with `ComposerHandle`
126
+ from `@djangocfg/ui-tools/composer-registry` — the chat suite can
127
+ register a NotionEditor as a composer if you ever want to swap them in
128
+ the chat input (unusual, but allowed).
129
+
130
+ ## Saving — dirty / pristine handling
131
+
132
+ The editor is **uncontrolled-ish**: it calls `onChange` on every
133
+ keystroke with the freshly-serialised markdown. The host owns state
134
+ and detects "dirty" however it likes.
135
+
136
+ Two gotchas the host needs to know about:
137
+
138
+ 1. **TipTap re-serialises markdown on mount** (trailing newline,
139
+ CRLF → LF normalisation). The first `onChange` after
140
+ `setContent(value)` is byte-different from `value` even though
141
+ nobody typed. If you compare `draft !== savedContent` literally,
142
+ the dirty indicator lights up on every file open. **Fix in the
143
+ host**: normalise both sides before comparing.
144
+
145
+ ```ts
146
+ const norm = (s: string) => s.replace(/\r\n/g, '\n').trimEnd();
147
+ const isDirty = norm(draft) !== norm(saved);
148
+ ```
149
+
150
+ 2. **Cmd+S only fires when focus is inside the editor**. If the user
151
+ clicked outside (header, sidebar) and presses Cmd+S, this hook
152
+ doesn't fire. Add a window-level `useHotkey('mod+s', save)` in the
153
+ host as a fallback — both paths call the same save fn.
154
+
155
+ See `cmdop/.../document-preview/viewers/text-viewer.tsx` for the
156
+ canonical wiring.
157
+
158
+ ## Markdown round-trip
159
+
160
+ | Input | Round-trips? | Notes |
161
+ | ---------------- | ------------ | ---------------------------------- |
162
+ | Headings | ✓ | H1-H4 only (StarterKit config) |
163
+ | Bold/italic/etc. | ✓ | |
164
+ | Inline code | ✓ | |
165
+ | Code blocks | ✓ | Language fence preserved by hljs |
166
+ | Bullet/ordered | ✓ | Nested too |
167
+ | Task lists | ✓ | GFM `- [x]` / `- [ ]` |
168
+ | Blockquote | ✓ | |
169
+ | Horizontal rule | ✓ | `---` |
170
+ | Tables | ✓ | GFM tables — alignment via `:--:` |
171
+ | Links | ✓ | autolinks too |
172
+ | Highlight | ✓ | `==text==` extension syntax |
173
+ | Images | mostly | Round-trip URLs, no upload yet |
174
+ | HTML passthrough | ✗ | Stripped on parse |
175
+ | Footnotes | ✗ | Not in StarterKit |
176
+
177
+ ## Known limitations
178
+
179
+ - **One editor per page (drag handle).**
180
+ `tiptap-extension-global-drag-handle` mints a single DOM grabber
181
+ attached to `document.body`. Mounting two `NotionEditor` instances
182
+ on the same page (e.g. a side-by-side diff) makes them fight over
183
+ the handle. If you need multiple editors, render only one with
184
+ drag-handle support.
185
+
186
+ - **Slash popup is portal'd to `document.body`.**
187
+ If the parent unmounts the editor mid-suggestion, the popup gets
188
+ cleaned up by ProseMirror's `onExit` — but a hostile race (route
189
+ change while menu is open) can leave an orphan div. Rare; visible
190
+ only via the inspector.
191
+
192
+ - **No image upload pipeline (yet).**
193
+ `Image` extension is not registered. Pasting an image from the
194
+ clipboard inserts the data-URL into the document (browser default)
195
+ but there's no upload integration. Add `@tiptap/extension-image` +
196
+ a custom paste handler when you have a target storage. See Novel's
197
+ `plugins/upload-images.tsx` for the canonical pattern.
198
+
199
+ - **Bubble menu uses `@tiptap/react/menus`'s `BubbleMenu`** (Tippy
200
+ under the hood). Slash menu uses `floating-ui` directly. Two
201
+ positioning libraries for one editor — kept this way because
202
+ `BubbleMenu` is opinionated about anchor invalidation and Tippy
203
+ handles it correctly; reimplementing on floating-ui would save
204
+ ~5 KB but cost a week of edge cases.
205
+
206
+ ## Storybook
207
+
208
+ Stories live at `apps/storybook/stories/ui-tools/markdown/NotionEditor.stories.tsx`:
209
+
210
+ - Default (empty editor with placeholder)
211
+ - With sample content (every supported block + serialised output panel)
212
+ - Auto-focus on mount
213
+ - Read-only
214
+ - Compact (240px min-height)
215
+
216
+ Each story renders a right-side panel showing the current serialised
217
+ markdown so you can watch the round-trip live as you type.
218
+
219
+ ## Wiring inside a host
220
+
221
+ The canonical host is `cmdop`'s document-preview text viewer:
222
+
223
+ ```tsx
224
+ // .md → NotionEditor only (it's already WYSIWYG, no Preview/Source split)
225
+ <div className="mx-auto w-full max-w-[820px] px-6 py-6">
226
+ <NotionEditor
227
+ value={draft}
228
+ onChange={handleChange}
229
+ onSave={save}
230
+ autoFocus
231
+ minHeight={420}
232
+ />
233
+ </div>
234
+ ```
235
+
236
+ Use `key={path}` on the wrapper if you remount per file — that's what
237
+ makes `autoFocus` fire on each file open.
@@ -18,7 +18,7 @@
18
18
  */
19
19
 
20
20
  import { Suspense, forwardRef, lazy } from 'react';
21
- import { LoadingFallback } from '../../../components';
21
+ import { LoadingFallback } from '../../../common';
22
22
  import type { NotionEditorHandle, NotionEditorProps } from './types';
23
23
 
24
24
  const NotionEditorImpl = lazy(() =>
@@ -18,10 +18,10 @@
18
18
 
19
19
  // Export tools as named exports (all use React.lazy internally)
20
20
  export { default as JsonTree } from './data/JsonTree';
21
- export type { JsonTreeConfig } from './data/JsonTree';
21
+ export type { JsonTreeProps, JsonValue, JsonAction, JsonSize } from './data/JsonTree';
22
22
  export { default as Mermaid } from './dev/Mermaid';
23
- export { default as PrettyCode } from './dev/PrettyCode';
24
- export type { Language } from './dev/PrettyCode';
23
+ export { default as PrettyCode } from './dev/code/PrettyCode';
24
+ export type { Language } from './dev/code/PrettyCode';
25
25
  export { LottiePlayer, useLottie, usePrefersReducedMotion } from './media/LottiePlayer';
26
26
  export type {
27
27
  LottiePlayerProps,
@@ -41,8 +41,8 @@ export * from './forms/JsonForm/templates';
41
41
  export * from './forms/JsonForm/utils';
42
42
 
43
43
  // Export OpenapiViewer
44
- export { default as OpenapiViewer } from './dev/OpenapiViewer';
45
- export type { PlaygroundConfig, SchemaSource, PlaygroundProps } from './dev/OpenapiViewer';
44
+ export { default as OpenapiViewer } from './dev/api/OpenapiViewer';
45
+ export type { PlaygroundConfig, SchemaSource, PlaygroundProps } from './dev/api/OpenapiViewer';
46
46
 
47
47
  // Export VideoPlayer (media-chrome shell with provider-aware canvases)
48
48
  export {
@@ -119,6 +119,8 @@ export {
119
119
  parseCron,
120
120
  isValidCron,
121
121
  humanizeCron,
122
+ getNextRuns,
123
+ formatNextRun,
122
124
  // Components
123
125
  ScheduleTypeSelector,
124
126
  TimeSelector,
@@ -126,6 +128,7 @@ export {
126
128
  MonthDayGrid,
127
129
  CustomInput,
128
130
  SchedulePreview,
131
+ CronPreview,
129
132
  } from './input/CronScheduler';
130
133
  export type {
131
134
  CronSchedulerProps,
@@ -135,6 +138,7 @@ export type {
135
138
  MonthDay,
136
139
  CronSchedulerState,
137
140
  CronSchedulerContextValue,
141
+ CronPreviewProps,
138
142
  } from './input/CronScheduler';
139
143
 
140
144
  // Export CodeEditor (Monaco ~550KB)
@@ -380,6 +384,20 @@ export type {
380
384
  ComboboxOption,
381
385
  } from './input/Combobox';
382
386
 
387
+ // Export ColorPalette (jalcoui port, Phase 1 Wave 3)
388
+ export {
389
+ ColorPalette,
390
+ ColorPaletteSwatch,
391
+ formatColor as colorPaletteFormatColor,
392
+ getReadableContrast as colorPaletteGetReadableContrast,
393
+ } from './visual/design/ColorPalette';
394
+ export type {
395
+ ColorEntry as ColorPaletteEntry,
396
+ ColorFormat as ColorPaletteFormat,
397
+ ColorPaletteMode,
398
+ ColorPaletteProps,
399
+ } from './visual/design/ColorPalette';
400
+
383
401
  // Export ColorPicker
384
402
  export {
385
403
  ColorPicker,
@@ -392,11 +410,11 @@ export {
392
410
  ColorPickerEyeDropper,
393
411
  ColorPickerFormatSelect,
394
412
  ColorPickerInput,
395
- } from './visual/ColorPicker';
413
+ } from './visual/design/ColorPicker';
396
414
  export type {
397
415
  ColorPickerProps,
398
416
  ColorPickerInputProps,
399
- } from './visual/ColorPicker';
417
+ } from './visual/design/ColorPicker';
400
418
 
401
419
  // Export FileUpload
402
420
  export {
@@ -420,8 +438,8 @@ export type {
420
438
  } from './forms/FileUpload';
421
439
 
422
440
  // Export Fps
423
- export { Fps } from './visual/Fps';
424
- export type { FpsProps } from './visual/Fps';
441
+ export { Fps } from './visual/indicators/Fps';
442
+ export type { FpsProps } from './visual/indicators/Fps';
425
443
 
426
444
  // Export Gauge
427
445
  export {
@@ -432,8 +450,8 @@ export {
432
450
  GaugeValueText,
433
451
  GaugeLabel,
434
452
  GaugeCombined,
435
- } from './visual/Gauge';
436
- export type { GaugeProps } from './visual/Gauge';
453
+ } from './visual/charts/Gauge';
454
+ export type { GaugeProps } from './visual/charts/Gauge';
437
455
 
438
456
  // Export Marquee
439
457
  export {
@@ -466,11 +484,133 @@ export type {
466
484
  export {
467
485
  Rating,
468
486
  RatingItem,
469
- } from './visual/Rating';
487
+ } from './visual/indicators/Rating';
470
488
  export type {
471
489
  RatingProps,
472
490
  RatingItemProps,
473
- } from './visual/Rating';
491
+ } from './visual/indicators/Rating';
492
+
493
+ // Export ActivityGraph (jalcoui port, Phase 1)
494
+ export { ActivityGraph } from './visual/charts/ActivityGraph';
495
+ export type { ActivityGraphProps, ActivityEntry } from './visual/charts/ActivityGraph';
496
+
497
+ // Export CommitGraph (jalcoui port, Phase 1)
498
+ export {
499
+ CommitGraph,
500
+ useLaneColors as useCommitGraphLaneColors,
501
+ useGraphLayout as useCommitGraphLayout,
502
+ pickLaneColor as pickCommitGraphLaneColor,
503
+ ROW_HEIGHT as COMMIT_GRAPH_ROW_HEIGHT,
504
+ } from './visual/charts/CommitGraph';
505
+ export type {
506
+ Commit,
507
+ CommitAuthor,
508
+ CommitGraphProps,
509
+ Edge as CommitGraphEdge,
510
+ EdgeType as CommitGraphEdgeType,
511
+ GraphRow as CommitGraphRow,
512
+ } from './visual/charts/CommitGraph';
513
+
514
+ // Export StatusIndicator (golden sample — jalcoui port, Phase 0)
515
+ export {
516
+ StatusIndicator,
517
+ STATUS_CONFIG,
518
+ TONE_CLASSES as STATUS_TONE_CLASSES,
519
+ statusIndicatorVariants,
520
+ } from './visual/indicators/StatusIndicator';
521
+ export type {
522
+ Status,
523
+ StatusTone,
524
+ StatusIndicatorProps,
525
+ StatusIndicatorSize,
526
+ } from './visual/indicators/StatusIndicator';
527
+
528
+ // Export EnvTable (jalcoui port, Phase 2)
529
+ export {
530
+ EnvTable,
531
+ ENV_TONE_CLASSES,
532
+ getEnvTone,
533
+ maskValue as envMaskValue,
534
+ useEnvMask,
535
+ } from './dev/ops/EnvTable';
536
+ export type {
537
+ EnvTableProps,
538
+ EnvVariable,
539
+ EnvEnvironment,
540
+ EnvBadgeTone,
541
+ } from './dev/ops/EnvTable';
542
+
543
+ // Export LogViewer (jalcoui port, Phase 2 Wave 2)
544
+ export {
545
+ LogViewer,
546
+ LEVEL_LABELS as LOG_LEVEL_LABELS,
547
+ LEVEL_TONE as LOG_LEVEL_TONE,
548
+ LOG_TONE_CLASSES,
549
+ getLevelToneClasses,
550
+ parseAnsi,
551
+ stripAnsi,
552
+ } from './dev/ops/LogViewer';
553
+ export type {
554
+ LogEntry,
555
+ LogLevel,
556
+ LogTone,
557
+ LogToneClasses,
558
+ LogViewerProps,
559
+ AnsiSegment,
560
+ } from './dev/ops/LogViewer';
561
+
562
+ // Export ApiRefTable (jalcoui port, Phase 2)
563
+ export {
564
+ ApiRefTable,
565
+ TYPE_TAG_CLASSES as API_REF_TYPE_TAG_CLASSES,
566
+ classifyTypeToken as classifyApiRefTypeToken,
567
+ splitTypeSignature as splitApiRefTypeSignature,
568
+ } from './dev/api/ApiRefTable';
569
+ export type {
570
+ ApiProp,
571
+ ApiRefTableProps,
572
+ TypeTag as ApiRefTypeTag,
573
+ } from './dev/api/ApiRefTable';
574
+
575
+ // Export DiffViewer (jalcoui port, Phase 2 Wave 3)
576
+ export {
577
+ DiffViewer,
578
+ DIFF_TONE_CLASSES,
579
+ diffLines,
580
+ parseUnifiedPatch,
581
+ computeDiffStats,
582
+ diffLineNumberWidth,
583
+ useDiff,
584
+ normalizeDiffLanguage,
585
+ } from './dev/code/DiffViewer';
586
+ export type {
587
+ DiffLayout,
588
+ DiffLine,
589
+ DiffLineType,
590
+ DiffStats,
591
+ DiffInput,
592
+ DiffToneClasses,
593
+ DiffViewerProps,
594
+ } from './dev/code/DiffViewer';
595
+
596
+ // Export RequestViewer (jalcoui port, Phase 2)
597
+ export { RequestViewer } from './dev/api/RequestViewer';
598
+ export type {
599
+ RequestViewerProps,
600
+ RequestViewerTab,
601
+ NetworkRequest,
602
+ HeaderEntry as RequestViewerHeaderEntry,
603
+ TimingEntry as RequestViewerTimingEntry,
604
+ } from './dev/api/RequestViewer';
605
+
606
+ // Export Sparkline (jalcoui port, Phase 1)
607
+ export { Sparkline } from './visual/charts/Sparkline';
608
+ export type {
609
+ SparklineProps,
610
+ SparklineColor,
611
+ SparklineVariant,
612
+ SparklineDatum,
613
+ } from './visual/charts/Sparkline';
474
614
 
475
615
  // Export DataGrid
476
616
  export {
@@ -4,7 +4,7 @@
4
4
  * Lazy-loaded Combobox Component
5
5
  */
6
6
 
7
- import { createLazyComponent, LoadingFallback } from '../../../components/lazy-wrapper';
7
+ import { createLazyComponent, LoadingFallback } from '../../../common/lazy-wrapper';
8
8
  import type {
9
9
  ComboboxProps,
10
10
  ComboboxTriggerProps,
@@ -0,0 +1,28 @@
1
+ # CronPreview
2
+
3
+ Read-only companion to `CronScheduler`. Renders a human-readable summary of a cron expression and an optional list of upcoming run times. Standalone — no `CronSchedulerProvider` required.
4
+
5
+ Use it in dashboards, list rows, and read-only schedule views.
6
+
7
+ ```tsx
8
+ import { CronPreview } from '@djangocfg/ui-tools/cron-scheduler';
9
+
10
+ <CronPreview value="0 9 * * 1-5" />
11
+ <CronPreview value="*/15 * * * *" nextRuns={5} />
12
+ ```
13
+
14
+ ## Props
15
+
16
+ | Prop | Type | Default | Description |
17
+ |---|---|---|---|
18
+ | `value` | `string` | — | Standard 5-field cron expression. |
19
+ | `title` | `string` | — | Optional heading above the summary. |
20
+ | `nextRuns` | `number` | `5` | Upcoming run times to display. `0` hides the list. |
21
+ | `showExpression` | `boolean` | `true` | Show the raw cron expression alongside the summary. |
22
+ | `referenceDate` | `Date` | `new Date()` | Base date for computing next runs. |
23
+
24
+ Storybook: `apps/storybook/stories/ui-tools/cron/CronPreview.stories.tsx`
25
+
26
+ ---
27
+
28
+ Adapted from jalcoui (MIT).
@@ -0,0 +1,136 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * CronPreview
5
+ *
6
+ * Read-only sibling of `CronScheduler`. Renders a human-readable summary
7
+ * for a cron expression plus an optional list of upcoming run times.
8
+ *
9
+ * Unlike `SchedulePreview` (which lives inside the editor and pulls its
10
+ * state from `CronSchedulerProvider`), `CronPreview` is fully standalone:
11
+ * pass a value, get a preview. Use it in dashboards, list rows, and
12
+ * read-only schedule views where the heavier editor is not needed.
13
+ *
14
+ * @example
15
+ * <CronPreview value="0 9 * * 1-5" />
16
+ *
17
+ * @example
18
+ * <CronPreview value="*\/15 * * * *" nextRuns={5} />
19
+ */
20
+
21
+ import * as React from 'react';
22
+ import { Calendar } from 'lucide-react';
23
+ import { cn } from '@djangocfg/ui-core/lib';
24
+ import { humanizeCron } from '../utils/cron-humanize';
25
+ import { getNextRuns, formatNextRun } from '../utils/cron-next-runs';
26
+ import { isValidCron } from '../utils/cron-parser';
27
+
28
+ export interface CronPreviewProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {
29
+ /** Cron expression (standard 5-field format, e.g. `"0 9 * * 1-5"`). */
30
+ value: string;
31
+ /** Optional heading shown above the summary. */
32
+ title?: string;
33
+ /**
34
+ * Number of upcoming run times to display.
35
+ * `0` hides the list. Defaults to `5`.
36
+ */
37
+ nextRuns?: number;
38
+ /** Show the raw cron expression alongside the summary. Defaults to `true`. */
39
+ showExpression?: boolean;
40
+ /** Base date for computing next runs. Defaults to "now". */
41
+ referenceDate?: Date;
42
+ /** Additional CSS classes for the outer container. */
43
+ className?: string;
44
+ }
45
+
46
+ export function CronPreview({
47
+ value,
48
+ title,
49
+ nextRuns = 5,
50
+ showExpression = true,
51
+ referenceDate,
52
+ className,
53
+ ...rest
54
+ }: CronPreviewProps) {
55
+ const trimmed = (value ?? '').trim();
56
+ const valid = isValidCron(trimmed);
57
+
58
+ const summary = React.useMemo(() => humanizeCron(trimmed), [trimmed]);
59
+
60
+ const runs = React.useMemo(() => {
61
+ if (!valid || nextRuns <= 0) return [];
62
+ return getNextRuns(trimmed, nextRuns, referenceDate ?? new Date());
63
+ }, [trimmed, valid, nextRuns, referenceDate]);
64
+
65
+ if (!valid) {
66
+ return (
67
+ <div
68
+ data-slot="cron-preview"
69
+ className={cn(
70
+ 'rounded-xl border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm text-destructive',
71
+ className
72
+ )}
73
+ {...rest}
74
+ >
75
+ Invalid cron expression: <code className="font-mono">{trimmed || '(empty)'}</code>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ return (
81
+ <div
82
+ data-slot="cron-preview"
83
+ role="status"
84
+ aria-live="polite"
85
+ className={cn(
86
+ 'overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-sm',
87
+ className
88
+ )}
89
+ {...rest}
90
+ >
91
+ {/* Header */}
92
+ <div className="flex items-start justify-between gap-3 border-b border-border/60 px-4 py-3">
93
+ <div className="flex min-w-0 items-start gap-2">
94
+ <Calendar aria-hidden="true" className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" />
95
+ <div className="flex min-w-0 flex-col gap-0.5">
96
+ {title && (
97
+ <h3 className="text-sm font-semibold text-foreground">{title}</h3>
98
+ )}
99
+ <p className="text-sm text-muted-foreground">{summary}</p>
100
+ </div>
101
+ </div>
102
+ {showExpression && (
103
+ <code className="shrink-0 rounded-md bg-muted px-2.5 py-1 font-mono text-xs text-foreground">
104
+ {trimmed}
105
+ </code>
106
+ )}
107
+ </div>
108
+
109
+ {/* Next runs */}
110
+ {runs.length > 0 && (
111
+ <div className="px-4 py-3">
112
+ <p className="mb-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
113
+ Next {runs.length === 1 ? 'run' : `${runs.length} runs`}
114
+ </p>
115
+ <ol className="flex flex-col gap-1">
116
+ {runs.map((run, i) => (
117
+ <li
118
+ key={run.toISOString()}
119
+ className="flex items-center gap-2 text-sm"
120
+ >
121
+ <span className="flex size-5 shrink-0 items-center justify-center rounded-full bg-muted text-[10px] font-semibold text-muted-foreground">
122
+ {i + 1}
123
+ </span>
124
+ <span className="font-mono text-xs text-foreground">
125
+ {formatNextRun(run)}
126
+ </span>
127
+ </li>
128
+ ))}
129
+ </ol>
130
+ </div>
131
+ )}
132
+ </div>
133
+ );
134
+ }
135
+
136
+ export default CronPreview;
@@ -22,3 +22,6 @@ export type { SchedulePreviewProps } from './SchedulePreview';
22
22
 
23
23
  export { CronCheatsheet } from './CronCheatsheet';
24
24
  export type { CronCheatsheetProps } from './CronCheatsheet';
25
+
26
+ export { CronPreview } from './CronPreview';
27
+ export type { CronPreviewProps } from './CronPreview';