@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
@@ -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';
@@ -17,7 +17,7 @@
17
17
  */
18
18
 
19
19
  import React, { lazy, Suspense } from 'react';
20
- import { LoadingFallback } from '../../../components';
20
+ import { LoadingFallback } from '../../../common';
21
21
  import type { CronSchedulerProps } from './types';
22
22
 
23
23
  // Lazy load the client component
@@ -78,6 +78,8 @@ export {
78
78
  parseCron,
79
79
  isValidCron,
80
80
  humanizeCron,
81
+ getNextRuns,
82
+ formatNextRun,
81
83
  } from './utils';
82
84
 
83
85
  // Re-export components for custom compositions
@@ -88,6 +90,8 @@ export {
88
90
  MonthDayGrid,
89
91
  CustomInput,
90
92
  SchedulePreview,
93
+ CronPreview,
91
94
  } from './components';
95
+ export type { CronPreviewProps } from './components';
92
96
 
93
97
  export default CronScheduler;
@@ -15,7 +15,7 @@
15
15
  * />
16
16
  */
17
17
 
18
- import { createLazyComponent, LoadingFallback } from '../../../components';
18
+ import { createLazyComponent, LoadingFallback } from '../../../common';
19
19
  import type { CronSchedulerProps } from './types';
20
20
 
21
21
  // Re-export types
@@ -28,6 +28,10 @@ export type {
28
28
  CronSchedulerState,
29
29
  } from './types';
30
30
 
31
+ // Re-export the read-only preview (small, no lazy needed — pure render).
32
+ export { CronPreview } from './components/CronPreview';
33
+ export type { CronPreviewProps } from './components/CronPreview';
34
+
31
35
  /**
32
36
  * LazyCronScheduler - Lazy-loaded cron expression builder
33
37
  *
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Cron Next Runs
3
+ *
4
+ * Computes upcoming run times for a standard 5-field cron expression
5
+ * (minute, hour, day-of-month, month, day-of-week). Supports `*`, lists
6
+ * (`1,2,3`), ranges (`1-5`), and step values (`*\/15`, `1-5/2`).
7
+ *
8
+ * Implementation note: this is a minute-resolution scanner — adequate for
9
+ * preview UIs (showing the next few runs). It does not attempt to support
10
+ * non-standard fields (seconds, year, `L`, `W`, `#`).
11
+ */
12
+
13
+ function parseField(field: string, min: number, max: number): number[] {
14
+ const values = new Set<number>();
15
+
16
+ for (const part of field.split(',')) {
17
+ const stepMatch = part.match(/^(.+)\/(\d+)$/);
18
+ const step = stepMatch ? parseInt(stepMatch[2], 10) : 1;
19
+ const range = stepMatch ? stepMatch[1] : part;
20
+
21
+ if (!Number.isFinite(step) || step < 1) continue;
22
+
23
+ if (range === '*') {
24
+ for (let i = min; i <= max; i += step) values.add(i);
25
+ } else if (range.includes('-')) {
26
+ const [start, end] = range.split('-').map(Number);
27
+ if (Number.isFinite(start) && Number.isFinite(end)) {
28
+ for (let i = start; i <= end; i += step) values.add(i);
29
+ }
30
+ } else {
31
+ const n = parseInt(range, 10);
32
+ if (Number.isFinite(n)) values.add(n);
33
+ }
34
+ }
35
+
36
+ return Array.from(values).sort((a, b) => a - b);
37
+ }
38
+
39
+ /**
40
+ * Compute the next `count` run times of a cron expression starting after
41
+ * `from` (exclusive). Returns an empty array for invalid expressions.
42
+ */
43
+ export function getNextRuns(cron: string, count: number, from: Date = new Date()): Date[] {
44
+ if (!cron || typeof cron !== 'string' || count <= 0) return [];
45
+
46
+ const fields = cron.trim().split(/\s+/);
47
+ if (fields.length !== 5) return [];
48
+
49
+ const minuteValues = parseField(fields[0], 0, 59);
50
+ const hourValues = parseField(fields[1], 0, 23);
51
+ const domValues = parseField(fields[2], 1, 31);
52
+ const monthValues = parseField(fields[3], 1, 12);
53
+ const dowValues = parseField(fields[4], 0, 6);
54
+
55
+ if (
56
+ minuteValues.length === 0 ||
57
+ hourValues.length === 0 ||
58
+ (fields[2] !== '*' && domValues.length === 0) ||
59
+ (fields[3] !== '*' && monthValues.length === 0) ||
60
+ (fields[4] !== '*' && dowValues.length === 0)
61
+ ) {
62
+ return [];
63
+ }
64
+
65
+ const minuteSet = new Set(minuteValues);
66
+ const hourSet = new Set(hourValues);
67
+ const domSet = fields[2] === '*' ? null : new Set(domValues);
68
+ const monthSet = fields[3] === '*' ? null : new Set(monthValues);
69
+ const dowSet = fields[4] === '*' ? null : new Set(dowValues);
70
+
71
+ const runs: Date[] = [];
72
+ const cursor = new Date(from);
73
+ cursor.setSeconds(0, 0);
74
+ cursor.setMinutes(cursor.getMinutes() + 1);
75
+
76
+ // cap at ~1 year of minutes — far enough for monthly schedules,
77
+ // tight enough that broken expressions return quickly.
78
+ const maxIterations = 366 * 24 * 60;
79
+
80
+ for (let i = 0; i < maxIterations && runs.length < count; i++) {
81
+ const m = cursor.getMinutes();
82
+ const h = cursor.getHours();
83
+ const d = cursor.getDate();
84
+ const mo = cursor.getMonth() + 1;
85
+ const w = cursor.getDay();
86
+
87
+ if (
88
+ minuteSet.has(m) &&
89
+ hourSet.has(h) &&
90
+ (domSet === null || domSet.has(d)) &&
91
+ (monthSet === null || monthSet.has(mo)) &&
92
+ (dowSet === null || dowSet.has(w))
93
+ ) {
94
+ runs.push(new Date(cursor));
95
+ }
96
+
97
+ cursor.setMinutes(cursor.getMinutes() + 1);
98
+ }
99
+
100
+ return runs;
101
+ }
102
+
103
+ /**
104
+ * Default human-friendly formatter for a next-run Date.
105
+ * Example: "Mon, Jan 5 at 9:00 AM"
106
+ */
107
+ export function formatNextRun(date: Date): string {
108
+ const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
109
+ const months = [
110
+ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
111
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
112
+ ];
113
+ const day = days[date.getDay()];
114
+ const month = months[date.getMonth()];
115
+ const d = date.getDate();
116
+ const h = date.getHours();
117
+ const m = date.getMinutes().toString().padStart(2, '0');
118
+ const period = h >= 12 ? 'PM' : 'AM';
119
+ const hour = h === 0 ? 12 : h > 12 ? h - 12 : h;
120
+
121
+ return `${day}, ${month} ${d} at ${hour}:${m} ${period}`;
122
+ }
@@ -10,3 +10,4 @@ export {
10
10
  getWeekdayName,
11
11
  getWeekdayShort,
12
12
  } from './cron-humanize';
13
+ export { getNextRuns, formatNextRun } from './cron-next-runs';
@@ -4,7 +4,7 @@
4
4
  * Lazy-loaded Scroller 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
  ScrollerProps,
10
10
  ScrollerItemProps,
@@ -4,7 +4,7 @@
4
4
  * Lazy-loaded Sortable 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
  SortableProps,
10
10
  SortableItemProps,
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { createLazyComponent } from '../../../components';
3
+ import { createLazyComponent } from '../../../common';
4
4
  import type { DictationFieldProps } from './widgets/DictationField';
5
5
 
6
6
  export const LazyDictationField = createLazyComponent<DictationFieldProps>(