@djangocfg/ui-tools 2.1.417 → 2.1.419

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/dist/audio-player/index.cjs +1 -2
  2. package/dist/audio-player/index.cjs.map +1 -1
  3. package/dist/audio-player/index.d.cts +3 -11
  4. package/dist/audio-player/index.d.ts +3 -11
  5. package/dist/audio-player/index.mjs +1 -2
  6. package/dist/audio-player/index.mjs.map +1 -1
  7. package/dist/file-icon/index.cjs +3 -3
  8. package/dist/file-icon/index.cjs.map +1 -1
  9. package/dist/file-icon/index.mjs +3 -3
  10. package/dist/file-icon/index.mjs.map +1 -1
  11. package/dist/tree/index.cjs +0 -3
  12. package/dist/tree/index.cjs.map +1 -1
  13. package/dist/tree/index.mjs +0 -3
  14. package/dist/tree/index.mjs.map +1 -1
  15. package/package.json +117 -36
  16. package/src/common/FloatingToolbar/actions/CopyAction.tsx +31 -0
  17. package/src/{components → common}/FloatingToolbar/actions/DownloadAction.tsx +15 -10
  18. package/src/common/FloatingToolbar/actions/ExpandAction.tsx +33 -0
  19. package/src/common/FloatingToolbar/actions/FullscreenAction.tsx +38 -0
  20. package/src/{components → common}/FloatingToolbar/index.tsx +39 -0
  21. package/src/lib/http.ts +64 -0
  22. package/src/tools/chat/index.ts +1 -1
  23. package/src/tools/chat/launcher/ChatFAB.tsx +66 -74
  24. package/src/tools/chat/launcher/header/ChatHeaderActionButton.tsx +2 -3
  25. package/src/tools/chat/lazy.tsx +1 -1
  26. package/src/tools/chat/messages/MessageBubble.tsx +1 -1
  27. package/src/tools/chat/messages/blocks/builtin.tsx +1 -1
  28. package/src/tools/chat/messages/blocks/renderers/CodeBlock.tsx +2 -2
  29. package/src/tools/chat/messages/blocks/renderers/JsonBlock.tsx +12 -1
  30. package/src/tools/data/DataGrid/lazy.tsx +1 -1
  31. package/src/tools/data/DataTable/lazy.tsx +1 -1
  32. package/src/tools/data/JsonTree/JsonViewer.tsx +720 -0
  33. package/src/tools/data/JsonTree/README.md +126 -73
  34. package/src/tools/data/JsonTree/index.tsx +3 -95
  35. package/src/tools/data/JsonTree/lazy.tsx +10 -50
  36. package/src/tools/data/JsonTree/types.ts +82 -63
  37. package/src/tools/data/Kanban/lazy.tsx +1 -1
  38. package/src/tools/data/Listbox/lazy.tsx +1 -1
  39. package/src/tools/data/Masonry/lazy.tsx +1 -1
  40. package/src/tools/data/Timeline/lazy.tsx +1 -1
  41. package/src/tools/data/Tree/components/TreeRow.tsx +0 -11
  42. package/src/tools/data/Tree/lazy.tsx +1 -1
  43. package/src/tools/dev/Map/lazy.tsx +1 -1
  44. package/src/tools/dev/Mermaid/Mermaid.client.tsx +2 -2
  45. package/src/tools/dev/Mermaid/lazy.tsx +1 -1
  46. package/src/tools/dev/api/ApiRefTable/ApiRefTable.tsx +65 -0
  47. package/src/tools/dev/api/ApiRefTable/README.md +31 -0
  48. package/src/tools/dev/api/ApiRefTable/components/Row.tsx +96 -0
  49. package/src/tools/dev/api/ApiRefTable/components/TypeDisplay.tsx +44 -0
  50. package/src/tools/dev/api/ApiRefTable/index.ts +6 -0
  51. package/src/tools/dev/api/ApiRefTable/lazy.tsx +21 -0
  52. package/src/tools/dev/api/ApiRefTable/types.ts +82 -0
  53. package/src/tools/dev/api/ApiRefTable/utils.ts +42 -0
  54. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/ApiIntroSection.tsx +1 -1
  55. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/index.tsx +1 -1
  56. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/index.tsx +1 -1
  57. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/ResponseBody.tsx +7 -21
  58. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/RequestPanel.tsx +1 -1
  59. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/PrettyView.tsx +13 -19
  60. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/types.ts +1 -1
  61. package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/lazy.tsx +1 -1
  62. package/src/tools/dev/api/RequestViewer/README.md +33 -0
  63. package/src/tools/dev/api/RequestViewer/RequestViewer.tsx +121 -0
  64. package/src/tools/dev/api/RequestViewer/components/BodyTab.tsx +44 -0
  65. package/src/tools/dev/api/RequestViewer/components/EmptyState.tsx +13 -0
  66. package/src/tools/dev/api/RequestViewer/components/HeadersTab.tsx +78 -0
  67. package/src/tools/dev/api/RequestViewer/components/TimingTab.tsx +113 -0
  68. package/src/tools/dev/api/RequestViewer/components/utils.ts +31 -0
  69. package/src/tools/dev/api/RequestViewer/index.ts +16 -0
  70. package/src/tools/dev/api/RequestViewer/lazy.tsx +30 -0
  71. package/src/tools/dev/api/RequestViewer/types.ts +81 -0
  72. package/src/tools/dev/code/DiffViewer/DiffViewer.tsx +144 -0
  73. package/src/tools/dev/code/DiffViewer/README.md +33 -0
  74. package/src/tools/dev/code/DiffViewer/components/CopyButton.tsx +49 -0
  75. package/src/tools/dev/code/DiffViewer/components/DiffLineContent.tsx +48 -0
  76. package/src/tools/dev/code/DiffViewer/components/SplitView.tsx +220 -0
  77. package/src/tools/dev/code/DiffViewer/components/UnifiedView.tsx +154 -0
  78. package/src/tools/dev/code/DiffViewer/hooks/useDiff.ts +47 -0
  79. package/src/tools/dev/code/DiffViewer/hooks/useHighlighter.ts +54 -0
  80. package/src/tools/dev/code/DiffViewer/index.ts +22 -0
  81. package/src/tools/dev/code/DiffViewer/lazy.tsx +22 -0
  82. package/src/tools/dev/code/DiffViewer/types.ts +109 -0
  83. package/src/tools/dev/code/DiffViewer/utils/computeDiff.ts +159 -0
  84. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/CollapseToggle.tsx +1 -1
  85. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/MarkdownMessage.tsx +1 -1
  86. package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/components.tsx +2 -2
  87. package/src/tools/dev/{PrettyCode → code/PrettyCode}/PrettyCode.client.tsx +2 -2
  88. package/src/tools/dev/{PrettyCode → code/PrettyCode}/lazy.tsx +1 -1
  89. package/src/tools/dev/ops/EnvTable/EnvTable.tsx +228 -0
  90. package/src/tools/dev/ops/EnvTable/README.md +29 -0
  91. package/src/tools/dev/ops/EnvTable/hooks/useEnvMask.ts +121 -0
  92. package/src/tools/dev/ops/EnvTable/index.ts +12 -0
  93. package/src/tools/dev/ops/EnvTable/lazy.tsx +21 -0
  94. package/src/tools/dev/ops/EnvTable/types.ts +76 -0
  95. package/src/tools/dev/ops/LogViewer/LogViewer.tsx +194 -0
  96. package/src/tools/dev/ops/LogViewer/README.md +30 -0
  97. package/src/tools/dev/ops/LogViewer/components/LogRow.tsx +151 -0
  98. package/src/tools/dev/ops/LogViewer/components/Toolbar.tsx +199 -0
  99. package/src/tools/dev/ops/LogViewer/hooks/useAutoScroll.ts +68 -0
  100. package/src/tools/dev/ops/LogViewer/hooks/useLogFilter.ts +58 -0
  101. package/src/tools/dev/ops/LogViewer/index.ts +18 -0
  102. package/src/tools/dev/ops/LogViewer/lazy.tsx +25 -0
  103. package/src/tools/dev/ops/LogViewer/types.ts +142 -0
  104. package/src/tools/dev/ops/LogViewer/utils/ansi.ts +231 -0
  105. package/src/tools/forms/CodeEditor/components/Editor.tsx +19 -0
  106. package/src/tools/forms/CodeEditor/hooks/useEditorTheme.ts +13 -73
  107. package/src/tools/forms/CodeEditor/lazy.tsx +1 -1
  108. package/src/tools/forms/CodeEditor/types/index.ts +7 -0
  109. package/src/tools/forms/FileUpload/lazy.tsx +1 -1
  110. package/src/tools/forms/JsonEditor/JsonEditor.tsx +115 -0
  111. package/src/tools/forms/JsonEditor/index.ts +1 -0
  112. package/src/tools/forms/JsonEditor/lazy.tsx +24 -0
  113. package/src/tools/forms/JsonForm/index.ts +1 -1
  114. package/src/tools/forms/JsonForm/lazy.tsx +1 -1
  115. package/src/tools/forms/MarkdownEditor/MarkdownEditor.tsx +40 -0
  116. package/src/tools/forms/MarkdownEditor/lazy.tsx +1 -1
  117. package/src/tools/forms/MarkdownEditor/styles.css +174 -21
  118. package/src/tools/forms/NotionEditor/CustomKeymap.ts +48 -0
  119. package/src/tools/forms/NotionEditor/LinkDialog.tsx +133 -0
  120. package/src/tools/forms/NotionEditor/NotionEditor.tsx +304 -0
  121. package/src/tools/forms/NotionEditor/README.md +237 -0
  122. package/src/tools/forms/NotionEditor/SlashExtension.ts +32 -0
  123. package/src/tools/forms/NotionEditor/SlashList.tsx +136 -0
  124. package/src/tools/forms/NotionEditor/TaskItemView.tsx +41 -0
  125. package/src/tools/forms/NotionEditor/createSlashSuggestion.ts +121 -0
  126. package/src/tools/forms/NotionEditor/extensions.ts +105 -0
  127. package/src/tools/forms/NotionEditor/index.ts +1 -0
  128. package/src/tools/forms/NotionEditor/lazy.tsx +44 -0
  129. package/src/tools/forms/NotionEditor/slashItems.ts +159 -0
  130. package/src/tools/forms/NotionEditor/styles.css +478 -0
  131. package/src/tools/forms/NotionEditor/types.ts +28 -0
  132. package/src/tools/index.ts +153 -13
  133. package/src/tools/input/Combobox/lazy.tsx +1 -1
  134. package/src/tools/input/CronScheduler/components/CronPreview.README.md +28 -0
  135. package/src/tools/input/CronScheduler/components/CronPreview.tsx +136 -0
  136. package/src/tools/input/CronScheduler/components/index.ts +3 -0
  137. package/src/tools/input/CronScheduler/index.tsx +5 -1
  138. package/src/tools/input/CronScheduler/lazy.tsx +5 -1
  139. package/src/tools/input/CronScheduler/utils/cron-next-runs.ts +122 -0
  140. package/src/tools/input/CronScheduler/utils/index.ts +1 -0
  141. package/src/tools/input/Scroller/lazy.tsx +1 -1
  142. package/src/tools/input/Sortable/lazy.tsx +1 -1
  143. package/src/tools/input/SpeechRecognition/lazy.tsx +1 -1
  144. package/src/tools/input/SpeechRecognition/widgets/VoiceComposerSlot.tsx +41 -36
  145. package/src/tools/media/AudioPlayer/PlayerShell.tsx +3 -11
  146. package/src/tools/media/AudioPlayer/types.ts +4 -11
  147. package/src/tools/media/ImageViewer/components/ImageToolbar.tsx +58 -47
  148. package/src/tools/media/ImageViewer/components/ImageViewer.tsx +35 -19
  149. package/src/tools/media/ImageViewer/lazy.tsx +1 -1
  150. package/src/tools/media/ImageViewer/types.ts +4 -0
  151. package/src/tools/media/LottiePlayer/lazy.tsx +1 -1
  152. package/src/tools/media/VideoPlayer/VideoPlayer.tsx +47 -1
  153. package/src/tools/media/VideoPlayer/parts/fullscreen.tsx +21 -4
  154. package/src/tools/media/VideoPlayer/parts/pip.tsx +21 -4
  155. package/src/tools/media/VideoPlayer/parts/play-button.tsx +21 -4
  156. package/src/tools/media/VideoPlayer/parts/playback-rate.tsx +19 -3
  157. package/src/tools/media/VideoPlayer/parts/volume.tsx +237 -18
  158. package/src/tools/media/VideoPlayer/styles/video-player.css +87 -7
  159. package/src/tools/media/VideoPlayer/types.ts +4 -0
  160. package/src/tools/overlay/ResponsiveDialog/lazy.tsx +1 -1
  161. package/src/tools/overlay/ScrollSpy/lazy.tsx +1 -1
  162. package/src/tools/overlay/SelectionToolbar/lazy.tsx +1 -1
  163. package/src/tools/overlay/Tour/lazy.tsx +1 -1
  164. package/src/tools/visual/Marquee/lazy.tsx +1 -1
  165. package/src/tools/visual/QRCode/lazy.tsx +1 -1
  166. package/src/tools/visual/charts/ActivityGraph/ActivityGraph.tsx +195 -0
  167. package/src/tools/visual/charts/ActivityGraph/README.md +28 -0
  168. package/src/tools/visual/charts/ActivityGraph/index.ts +8 -0
  169. package/src/tools/visual/charts/ActivityGraph/lazy.tsx +21 -0
  170. package/src/tools/visual/charts/ActivityGraph/types.ts +59 -0
  171. package/src/tools/visual/charts/ActivityGraph/utils.ts +88 -0
  172. package/src/tools/visual/charts/CommitGraph/CommitGraph.tsx +80 -0
  173. package/src/tools/visual/charts/CommitGraph/README.md +28 -0
  174. package/src/tools/visual/charts/CommitGraph/components/CommitDetail.tsx +107 -0
  175. package/src/tools/visual/charts/CommitGraph/components/CommitRow.tsx +122 -0
  176. package/src/tools/visual/charts/CommitGraph/components/Rails.tsx +171 -0
  177. package/src/tools/visual/charts/CommitGraph/hooks/useGraphLayout.ts +169 -0
  178. package/src/tools/visual/charts/CommitGraph/hooks/useLaneColors.ts +45 -0
  179. package/src/tools/visual/charts/CommitGraph/index.ts +14 -0
  180. package/src/tools/visual/charts/CommitGraph/lazy.tsx +25 -0
  181. package/src/tools/visual/charts/CommitGraph/types.ts +85 -0
  182. package/src/tools/visual/charts/CommitGraph/utils.ts +53 -0
  183. package/src/tools/visual/{Gauge → charts/Gauge}/lazy.tsx +1 -1
  184. package/src/tools/visual/charts/Sparkline/README.md +29 -0
  185. package/src/tools/visual/charts/Sparkline/Sparkline.tsx +217 -0
  186. package/src/tools/visual/charts/Sparkline/index.ts +9 -0
  187. package/src/tools/visual/charts/Sparkline/lazy.tsx +26 -0
  188. package/src/tools/visual/charts/Sparkline/types.ts +58 -0
  189. package/src/tools/visual/design/ColorPalette/ColorPalette.tsx +129 -0
  190. package/src/tools/visual/design/ColorPalette/README.md +34 -0
  191. package/src/tools/visual/design/ColorPalette/components/Swatch.tsx +102 -0
  192. package/src/tools/visual/design/ColorPalette/hooks/useCopyToClipboard.ts +41 -0
  193. package/src/tools/visual/design/ColorPalette/index.ts +12 -0
  194. package/src/tools/visual/design/ColorPalette/lazy.tsx +21 -0
  195. package/src/tools/visual/design/ColorPalette/types.ts +63 -0
  196. package/src/tools/visual/design/ColorPalette/utils.ts +83 -0
  197. package/src/tools/visual/{ColorPicker → design/ColorPicker}/lazy.tsx +1 -1
  198. package/src/tools/visual/{FileIcon → design/FileIcon}/treeAdapter.tsx +1 -1
  199. package/src/tools/visual/{Fps → indicators/Fps}/lazy.tsx +1 -1
  200. package/src/tools/visual/{Rating → indicators/Rating}/lazy.tsx +1 -1
  201. package/src/tools/visual/indicators/StatusIndicator/README.md +28 -0
  202. package/src/tools/visual/indicators/StatusIndicator/StatusIndicator.tsx +83 -0
  203. package/src/tools/visual/indicators/StatusIndicator/index.ts +14 -0
  204. package/src/tools/visual/indicators/StatusIndicator/lazy.tsx +21 -0
  205. package/src/tools/visual/indicators/StatusIndicator/types.ts +133 -0
  206. package/src/components/FloatingToolbar/actions/CopyAction.tsx +0 -22
  207. package/src/components/FloatingToolbar/actions/ExpandAction.tsx +0 -25
  208. package/src/components/FloatingToolbar/actions/FullscreenAction.tsx +0 -30
  209. package/src/tools/data/JsonTree/components/JsonContent.tsx +0 -197
  210. package/src/tools/data/JsonTree/hooks/useJsonExpand.ts +0 -50
  211. /package/src/{components → common}/FloatingToolbar/FloatingToolbar.css +0 -0
  212. /package/src/{components → common}/FloatingToolbar/actions/index.ts +0 -0
  213. /package/src/{components → common}/FloatingToolbar/hooks/useElementCorner.ts +0 -0
  214. /package/src/{components → common}/FloatingToolbar/hooks/useScrollIsolation.ts +0 -0
  215. /package/src/{components → common}/index.ts +0 -0
  216. /package/src/{components → common}/lazy-wrapper.tsx +0 -0
  217. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/README.md +0 -0
  218. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/DocsView.tsx +0 -0
  219. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/LanguageTabs.tsx +0 -0
  220. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/CodeSamples/useCodeSnippet.ts +0 -0
  221. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/MetaActions.tsx +0 -0
  222. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/MethodBadge.tsx +0 -0
  223. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Header/PathDisplay.tsx +0 -0
  224. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/ParamGroup.tsx +0 -0
  225. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/ParamRow.tsx +0 -0
  226. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Parameters/index.tsx +0 -0
  227. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/RequestBody/index.tsx +0 -0
  228. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/ResponseRow.tsx +0 -0
  229. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/StatusTag.tsx +0 -0
  230. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Responses/index.tsx +0 -0
  231. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/FieldRow.tsx +0 -0
  232. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts +0 -0
  233. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/index.tsx +0 -0
  234. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/SchemaFields/types.ts +0 -0
  235. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/SectionHeader.tsx +0 -0
  236. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/defaults.ts +0 -0
  237. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/Section/index.tsx +0 -0
  238. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/context.tsx +0 -0
  239. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/hooks/useSectionHash.ts +0 -0
  240. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/index.tsx +0 -0
  241. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/store/index.ts +0 -0
  242. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/store/selectors.ts +0 -0
  243. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/EndpointDoc/types.ts +0 -0
  244. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/SchemaCopyMenu.tsx +0 -0
  245. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/BrandHeader.tsx +0 -0
  246. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/CategoryBlock.tsx +0 -0
  247. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/EndpointRow.tsx +0 -0
  248. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SchemaSection.tsx +0 -0
  249. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SearchInput.tsx +0 -0
  250. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/SidebarBody.tsx +0 -0
  251. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/Toolbar.tsx +0 -0
  252. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/buildVM.ts +0 -0
  253. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/index.tsx +0 -0
  254. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/types.ts +0 -0
  255. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/Sidebar/useDebouncedValue.ts +0 -0
  256. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/SlideInPlayground.tsx +0 -0
  257. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/TryItSheet.tsx +0 -0
  258. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/anchor.ts +0 -0
  259. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/grouping.ts +0 -0
  260. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/index.tsx +0 -0
  261. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/DocsLayout/sidebarLabel.ts +0 -0
  262. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/index.ts +0 -0
  263. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/BodyFormEditor.tsx +0 -0
  264. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/EndpointDraftSync.tsx +0 -0
  265. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/EndpointResetButton.tsx +0 -0
  266. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/PreviewView.tsx +0 -0
  267. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/RawView.tsx +0 -0
  268. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/StatusBar.tsx +0 -0
  269. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/ViewTabs.tsx +0 -0
  270. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/detectContent.ts +0 -0
  271. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/index.tsx +0 -0
  272. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ResponsePanel/useResponseView.ts +0 -0
  273. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/SendButton.tsx +0 -0
  274. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/components/shared/ui.tsx +0 -0
  275. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/constants.ts +0 -0
  276. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/context/PlaygroundContext.tsx +0 -0
  277. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/index.ts +0 -0
  278. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useDocsUrlSync.ts +0 -0
  279. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useEndpointDraft.ts +0 -0
  280. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useMobile.ts +0 -0
  281. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/hooks/useOpenApiSchema.ts +0 -0
  282. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/index.tsx +0 -0
  283. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/types.ts +0 -0
  284. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/apiKeyManager.ts +0 -0
  285. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/codeSamples.ts +0 -0
  286. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/formatters.ts +0 -0
  287. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/index.ts +0 -0
  288. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/operationToHar.ts +0 -0
  289. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/sampler.ts +0 -0
  290. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/schemaExport.ts +0 -0
  291. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/scrollParent.ts +0 -0
  292. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/url.ts +0 -0
  293. /package/src/tools/dev/{OpenapiViewer → api/OpenapiViewer}/utils/versionManager.ts +0 -0
  294. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/ActionRow.tsx +0 -0
  295. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/ChatMessageRow.tsx +0 -0
  296. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/CodeBlock.tsx +0 -0
  297. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/README.md +0 -0
  298. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/index.ts +0 -0
  299. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/linkRules.ts +0 -0
  300. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/plainText.ts +0 -0
  301. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/sanitize.ts +0 -0
  302. /package/src/tools/dev/{MarkdownMessage → code/MarkdownMessage}/types.ts +0 -0
  303. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/README.md +0 -0
  304. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/index.tsx +0 -0
  305. /package/src/tools/dev/{PrettyCode → code/PrettyCode}/registerPrismLanguages.ts +0 -0
  306. /package/src/tools/visual/{Gauge → charts/Gauge}/Gauge.tsx +0 -0
  307. /package/src/tools/visual/{Gauge → charts/Gauge}/index.ts +0 -0
  308. /package/src/tools/visual/{Gauge → charts/Gauge}/types.ts +0 -0
  309. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/ColorPicker.tsx +0 -0
  310. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/ColorPickerContext.tsx +0 -0
  311. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/ColorPickerStore.tsx +0 -0
  312. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/context/index.ts +0 -0
  313. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/index.ts +0 -0
  314. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/lib/color-utils.ts +0 -0
  315. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerAlphaSlider.tsx +0 -0
  316. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerArea.tsx +0 -0
  317. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerEyeDropper.tsx +0 -0
  318. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerFormatSelect.tsx +0 -0
  319. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerHueSlider.tsx +0 -0
  320. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerInput.tsx +0 -0
  321. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/ColorPickerSwatch.tsx +0 -0
  322. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/parts/index.ts +0 -0
  323. /package/src/tools/visual/{ColorPicker → design/ColorPicker}/types.ts +0 -0
  324. /package/src/tools/visual/{FileIcon → design/FileIcon}/FileIcon.tsx +0 -0
  325. /package/src/tools/visual/{FileIcon → design/FileIcon}/get-file-icon.ts +0 -0
  326. /package/src/tools/visual/{FileIcon → design/FileIcon}/icons/icon-data.ts +0 -0
  327. /package/src/tools/visual/{FileIcon → design/FileIcon}/index.ts +0 -0
  328. /package/src/tools/visual/{FileIcon → design/FileIcon}/loader.ts +0 -0
  329. /package/src/tools/visual/{FileIcon → design/FileIcon}/specialFolders.ts +0 -0
  330. /package/src/tools/visual/{Fps → indicators/Fps}/Fps.tsx +0 -0
  331. /package/src/tools/visual/{Fps → indicators/Fps}/index.ts +0 -0
  332. /package/src/tools/visual/{Fps → indicators/Fps}/types.ts +0 -0
  333. /package/src/tools/visual/{Rating → indicators/Rating}/Rating.tsx +0 -0
  334. /package/src/tools/visual/{Rating → indicators/Rating}/index.ts +0 -0
  335. /package/src/tools/visual/{Rating → indicators/Rating}/types.ts +0 -0
@@ -0,0 +1,58 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ import type * as React from 'react';
4
+
5
+ /**
6
+ * Semantic color token name used for the sparkline stroke / area fill.
7
+ *
8
+ * Resolves at runtime via `useThemeColor(color)` from
9
+ * `@djangocfg/ui-core/styles/palette`, so it follows the active theme preset
10
+ * — never reference raw Tailwind scales (`emerald-500`, `sky-400`, …).
11
+ */
12
+ export type SparklineColor =
13
+ | 'primary'
14
+ | 'success'
15
+ | 'warning'
16
+ | 'destructive'
17
+ | 'info';
18
+
19
+ /**
20
+ * Sparkline chart variant.
21
+ *
22
+ * - `line` — just the stroke.
23
+ * - `area` — stroke + alpha-filled area underneath.
24
+ * - `bar` — discrete bars per data point.
25
+ */
26
+ export type SparklineVariant = 'line' | 'area' | 'bar';
27
+
28
+ /**
29
+ * A datum is either a bare number or an `{ value, label? }` object. The
30
+ * optional `label` is used for `aria-label` enrichment only — it never renders
31
+ * inside the SVG.
32
+ */
33
+ export type SparklineDatum = number | { value: number; label?: string };
34
+
35
+ export interface SparklineProps
36
+ extends Omit<React.ComponentProps<'div'>, 'children'> {
37
+ /** Data points. Empty array renders nothing. */
38
+ data: SparklineDatum[];
39
+ /** Sparkline chart variant. @default 'line' */
40
+ variant?: SparklineVariant;
41
+ /**
42
+ * Semantic color token. Resolved via `useThemeColor()` — respects the
43
+ * active theme preset. @default 'primary'
44
+ */
45
+ color?: SparklineColor;
46
+ /** SVG width in pixels. @default 120 */
47
+ width?: number;
48
+ /** SVG height in pixels. @default 32 */
49
+ height?: number;
50
+ /** Line stroke width (ignored for `bar`). @default 1.5 */
51
+ strokeWidth?: number;
52
+ /** Show a filled dot at the latest data point. @default true */
53
+ showEndpoint?: boolean;
54
+ /** Show a faint dashed line at the average value. @default false */
55
+ showBaseline?: boolean;
56
+ /** Optional accessible label for the chart. */
57
+ ariaLabel?: string;
58
+ }
@@ -0,0 +1,129 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+ //
3
+ // Grid of color swatches with click-to-copy in hex / rgb / hsl.
4
+ // Pulls colors from one of three sources via `mode`:
5
+ // - 'theme' → useThemePalette() (semantic tokens of the active theme)
6
+ // - 'preset' → useStylePresets() (status preset families)
7
+ // - 'custom' → caller-provided `colors` array
8
+ //
9
+ // Chrome (frame, value label) uses semantic Tailwind tokens; the swatch
10
+ // background uses inline `style={{ backgroundColor: hex }}` so it stays
11
+ // honest regardless of the active theme. See CONTRACT.md §2/§3.
12
+
13
+ 'use client';
14
+
15
+ import * as React from 'react';
16
+ import { cn } from '@djangocfg/ui-core/lib';
17
+ import { useThemePalette, useStylePresets } from '@djangocfg/ui-core/styles/palette';
18
+ import { Swatch } from './components/Swatch';
19
+ import type { ColorEntry, ColorPaletteMode, ColorPaletteProps } from './types';
20
+
21
+ function resolveMode(
22
+ mode: ColorPaletteMode | undefined,
23
+ colors: ColorEntry[] | undefined,
24
+ ): ColorPaletteMode {
25
+ if (mode) return mode;
26
+ return colors && colors.length > 0 ? 'custom' : 'theme';
27
+ }
28
+
29
+ /**
30
+ * Build the swatch list for `mode === 'theme'` — semantic tokens of the
31
+ * current theme. Includes the foreground/background pair plus brand and
32
+ * status families so a docs page can show "what does this preset look
33
+ * like" at a glance.
34
+ */
35
+ function useThemeEntries(): ColorEntry[] {
36
+ const palette = useThemePalette();
37
+ return React.useMemo<ColorEntry[]>(
38
+ () => [
39
+ { name: 'Background', value: palette.background },
40
+ { name: 'Foreground', value: palette.foreground },
41
+ { name: 'Card', value: palette.card },
42
+ { name: 'Muted', value: palette.muted },
43
+ { name: 'Muted Foreground', value: palette.mutedForeground },
44
+ { name: 'Border', value: palette.border },
45
+ { name: 'Primary', value: palette.primary },
46
+ { name: 'Secondary', value: palette.secondary },
47
+ { name: 'Accent', value: palette.accent },
48
+ { name: 'Destructive', value: palette.destructive },
49
+ { name: 'Success', value: palette.success },
50
+ { name: 'Warning', value: palette.warning },
51
+ { name: 'Info', value: palette.info },
52
+ ],
53
+ [palette],
54
+ );
55
+ }
56
+
57
+ /**
58
+ * Build the swatch list for `mode === 'preset'` — the status / brand
59
+ * families exposed by `useStylePresets()`. Renders the `fill` color
60
+ * for each preset; consumers needing stroke/foreground should query
61
+ * the preset hooks directly.
62
+ */
63
+ function usePresetEntries(): ColorEntry[] {
64
+ const presets = useStylePresets();
65
+ return React.useMemo<ColorEntry[]>(
66
+ () => [
67
+ { name: 'Primary', value: presets.primary.fill },
68
+ { name: 'Success', value: presets.success.fill },
69
+ { name: 'Warning', value: presets.warning.fill },
70
+ { name: 'Danger', value: presets.danger.fill },
71
+ { name: 'Info', value: presets.info.fill },
72
+ { name: 'Chart 3', value: presets.chart3.fill },
73
+ { name: 'Chart 4', value: presets.chart4.fill },
74
+ { name: 'Chart 5', value: presets.chart5.fill },
75
+ ],
76
+ [presets],
77
+ );
78
+ }
79
+
80
+ export function ColorPalette({
81
+ mode,
82
+ colors,
83
+ columns = 4,
84
+ copyFormat = 'hex',
85
+ showName = true,
86
+ showValue = true,
87
+ className,
88
+ style,
89
+ ...rest
90
+ }: ColorPaletteProps) {
91
+ // Always call both hooks so React keeps a stable order regardless of `mode`.
92
+ const themeEntries = useThemeEntries();
93
+ const presetEntries = usePresetEntries();
94
+
95
+ const resolvedMode = resolveMode(mode, colors);
96
+ const entries = React.useMemo<ColorEntry[]>(() => {
97
+ if (resolvedMode === 'theme') return themeEntries;
98
+ if (resolvedMode === 'preset') return presetEntries;
99
+ return colors ?? [];
100
+ }, [resolvedMode, themeEntries, presetEntries, colors]);
101
+
102
+ const gridStyle = React.useMemo<React.CSSProperties>(
103
+ () => ({
104
+ ...style,
105
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
106
+ }),
107
+ [style, columns],
108
+ );
109
+
110
+ return (
111
+ <div
112
+ data-slot="color-palette"
113
+ data-mode={resolvedMode}
114
+ className={cn('grid gap-3', className)}
115
+ style={gridStyle}
116
+ {...rest}
117
+ >
118
+ {entries.map((color) => (
119
+ <Swatch
120
+ key={`${color.name}-${color.value}`}
121
+ color={color}
122
+ copyFormat={copyFormat}
123
+ showName={showName}
124
+ showValue={showValue}
125
+ />
126
+ ))}
127
+ </div>
128
+ );
129
+ }
@@ -0,0 +1,34 @@
1
+ # ColorPalette
2
+
3
+ Grid of color swatches with copy-on-click. Source can be the active theme, a status preset family, or a custom list.
4
+
5
+ ```tsx
6
+ import { ColorPalette } from '@djangocfg/ui-tools/color-palette';
7
+
8
+ // Render the current theme tokens
9
+ <ColorPalette mode="theme" columns={4} />
10
+
11
+ // Custom swatches
12
+ <ColorPalette
13
+ mode="custom"
14
+ colors={[{ name: 'Brand', value: '#0989aa' }]}
15
+ copyFormat="hex"
16
+ />
17
+ ```
18
+
19
+ ## Props
20
+
21
+ | Prop | Type | Default | Description |
22
+ |---|---|---|---|
23
+ | `mode` | `'theme' \| 'preset' \| 'custom'` | `'custom'` if `colors` provided, else `'theme'` | Where swatches come from. |
24
+ | `colors` | `ColorEntry[]` | — | Required when `mode === 'custom'`. |
25
+ | `columns` | `number` | `4` | Grid columns. |
26
+ | `copyFormat` | `'hex' \| 'rgb' \| 'hsl'` | `'hex'` | Format of the copied + rendered value. |
27
+ | `showName` | `boolean` | `true` | Show the color label. |
28
+ | `showValue` | `boolean` | `true` | Show the color value string. |
29
+
30
+ Storybook: `apps/storybook/stories/ui-tools/visual/ColorPalette.stories.tsx`
31
+
32
+ ---
33
+
34
+ Adapted from jalcoui (MIT).
@@ -0,0 +1,102 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import * as React from 'react';
6
+ import { Check, Copy } from 'lucide-react';
7
+ import { cn } from '@djangocfg/ui-core/lib';
8
+ import { useCopyToClipboard } from '../hooks/useCopyToClipboard';
9
+ import { formatColor, getReadableContrast } from '../utils';
10
+ import type { ColorEntry, ColorFormat } from '../types';
11
+
12
+ export interface SwatchProps {
13
+ color: ColorEntry;
14
+ copyFormat: ColorFormat;
15
+ showName: boolean;
16
+ showValue: boolean;
17
+ }
18
+
19
+ /**
20
+ * Single color swatch — colored block on top, optional `name` +
21
+ * formatted `value` row below. Click anywhere copies the value in
22
+ * the configured {@link ColorFormat}.
23
+ *
24
+ * Background uses inline `style={{ backgroundColor }}` (hex) so the
25
+ * color is rendered verbatim — not via Tailwind's color tokens.
26
+ * Chrome (border, value text) flows through semantic tokens so the
27
+ * frame still respects the active theme preset.
28
+ */
29
+ export function Swatch({ color, copyFormat, showName, showValue }: SwatchProps) {
30
+ const { copied, copy } = useCopyToClipboard();
31
+ const formattedValue = React.useMemo(
32
+ () => formatColor(color.value, copyFormat),
33
+ [color.value, copyFormat],
34
+ );
35
+ const contrast = React.useMemo(
36
+ () => getReadableContrast(color.value),
37
+ [color.value],
38
+ );
39
+
40
+ const handleCopy = React.useCallback(() => {
41
+ void copy(formattedValue);
42
+ }, [copy, formattedValue]);
43
+
44
+ const iconColor = contrast === 'light' ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.85)';
45
+
46
+ return (
47
+ <button
48
+ type="button"
49
+ onClick={handleCopy}
50
+ data-slot="color-swatch"
51
+ data-copied={copied || undefined}
52
+ aria-label={`Copy ${color.name}: ${formattedValue}`}
53
+ title={color.description ?? `${color.name} — ${formattedValue}`}
54
+ className={cn(
55
+ 'group relative flex flex-col overflow-hidden rounded-lg border border-border/60 bg-card text-left shadow-xs outline-none transition-colors',
56
+ 'hover:border-border focus-visible:ring-[3px] focus-visible:ring-ring/50',
57
+ )}
58
+ >
59
+ <div
60
+ className="relative flex h-20 items-center justify-center sm:h-24"
61
+ style={{ backgroundColor: color.value }}
62
+ >
63
+ {/* Copy / Check icon — hex color resolved in JS, theme tokens skipped on purpose
64
+ because the swatch background is the user-supplied hex, not a token. */}
65
+ <span
66
+ className={cn(
67
+ 'inline-flex items-center justify-center rounded-full p-1.5 transition-opacity',
68
+ copied ? 'opacity-100' : 'opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100',
69
+ )}
70
+ style={{ color: iconColor }}
71
+ aria-hidden="true"
72
+ >
73
+ {copied ? <Check className="size-4" /> : <Copy className="size-4" />}
74
+ </span>
75
+
76
+ {copied && (
77
+ <span
78
+ data-slot="color-swatch-toast"
79
+ className="absolute bottom-1.5 right-1.5 rounded-md bg-card/90 px-1.5 py-0.5 text-[10px] font-medium text-foreground shadow-sm backdrop-blur"
80
+ >
81
+ Copied!
82
+ </span>
83
+ )}
84
+ </div>
85
+
86
+ {(showName || showValue) && (
87
+ <div className="flex flex-col gap-0.5 bg-card px-3 py-2">
88
+ {showName && (
89
+ <span className="truncate text-xs font-medium text-foreground">
90
+ {color.name}
91
+ </span>
92
+ )}
93
+ {showValue && (
94
+ <span className="truncate font-mono text-[11px] text-muted-foreground">
95
+ {formattedValue}
96
+ </span>
97
+ )}
98
+ </div>
99
+ )}
100
+ </button>
101
+ );
102
+ }
@@ -0,0 +1,41 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import * as React from 'react';
6
+
7
+ /**
8
+ * Copy a string to the clipboard and flash a `copied` flag for
9
+ * `resetMs` (default 1500ms). Safe to call on browsers without
10
+ * `navigator.clipboard` — returns silently.
11
+ */
12
+ export function useCopyToClipboard(resetMs = 1500): {
13
+ copied: boolean;
14
+ copy: (text: string) => Promise<void>;
15
+ } {
16
+ const [copied, setCopied] = React.useState(false);
17
+ const timerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
18
+
19
+ React.useEffect(() => {
20
+ return () => {
21
+ if (timerRef.current) clearTimeout(timerRef.current);
22
+ };
23
+ }, []);
24
+
25
+ const copy = React.useCallback(
26
+ async (text: string) => {
27
+ try {
28
+ if (typeof navigator === 'undefined' || !navigator.clipboard) return;
29
+ await navigator.clipboard.writeText(text);
30
+ setCopied(true);
31
+ if (timerRef.current) clearTimeout(timerRef.current);
32
+ timerRef.current = setTimeout(() => setCopied(false), resetMs);
33
+ } catch {
34
+ // Clipboard API not available / permission denied — ignore.
35
+ }
36
+ },
37
+ [resetMs],
38
+ );
39
+
40
+ return { copied, copy };
41
+ }
@@ -0,0 +1,12 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ export { ColorPalette } from './ColorPalette';
4
+ export { Swatch as ColorPaletteSwatch } from './components/Swatch';
5
+ export { useCopyToClipboard } from './hooks/useCopyToClipboard';
6
+ export { formatColor, getReadableContrast } from './utils';
7
+ export type {
8
+ ColorEntry,
9
+ ColorFormat,
10
+ ColorPaletteMode,
11
+ ColorPaletteProps,
12
+ } from './types';
@@ -0,0 +1,21 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ 'use client';
4
+
5
+ import { createLazyComponent } from '../../../../common/lazy-wrapper';
6
+ import type { ColorPaletteProps } from './types';
7
+
8
+ export const LazyColorPalette = createLazyComponent<ColorPaletteProps>(
9
+ () => import('./ColorPalette').then((m) => ({ default: m.ColorPalette })),
10
+ {
11
+ displayName: 'LazyColorPalette',
12
+ fallback: (
13
+ <div
14
+ data-slot="color-palette-skeleton"
15
+ className="grid h-32 animate-pulse gap-3 rounded-lg bg-muted"
16
+ />
17
+ ),
18
+ },
19
+ );
20
+
21
+ export type { ColorPaletteProps } from './types';
@@ -0,0 +1,63 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ import type * as React from 'react';
4
+
5
+ /**
6
+ * Display format for the copied / rendered color value.
7
+ *
8
+ * - `hex` — `#0989aa` (default). Canvas2D / SVG friendly.
9
+ * - `rgb` — `rgb(9, 137, 170)`.
10
+ * - `hsl` — `hsl(192, 90%, 35%)`.
11
+ */
12
+ export type ColorFormat = 'hex' | 'rgb' | 'hsl';
13
+
14
+ /**
15
+ * A single color entry rendered as one swatch.
16
+ *
17
+ * `value` is always a hex string (`#rrggbb`). Resolve theme tokens
18
+ * to hex via `useThemeColor(...)` before passing them in.
19
+ */
20
+ export interface ColorEntry {
21
+ /** Display name (e.g. "Primary", "Success", "brand-accent"). */
22
+ name: string;
23
+ /** Hex color value, e.g. `#0989aa`. */
24
+ value: string;
25
+ /** Optional usage note. */
26
+ description?: string;
27
+ }
28
+
29
+ /**
30
+ * Source of swatches.
31
+ *
32
+ * - `theme` — semantic tokens from `useThemePalette()` (background,
33
+ * foreground, primary, secondary, muted, accent, destructive, …).
34
+ * - `preset` — status preset family from `useStylePresets()`
35
+ * (primary, success, warning, danger, info, chart3-5).
36
+ * - `custom` — caller-provided `colors` array.
37
+ */
38
+ export type ColorPaletteMode = 'theme' | 'preset' | 'custom';
39
+
40
+ export interface ColorPaletteProps
41
+ extends Omit<React.ComponentProps<'div'>, 'children'> {
42
+ /**
43
+ * Where swatches come from. Defaults to `'custom'` when `colors` is
44
+ * provided, otherwise `'theme'`.
45
+ */
46
+ mode?: ColorPaletteMode;
47
+ /**
48
+ * Explicit list of swatches (required when `mode === 'custom'`).
49
+ * Ignored for `'theme'` / `'preset'`.
50
+ */
51
+ colors?: ColorEntry[];
52
+ /** Grid column count. @default 4 */
53
+ columns?: number;
54
+ /**
55
+ * Format of the copied value AND the rendered value text.
56
+ * @default 'hex'
57
+ */
58
+ copyFormat?: ColorFormat;
59
+ /** Show the color name label below the swatch. @default true */
60
+ showName?: boolean;
61
+ /** Show the color value string below the swatch. @default true */
62
+ showValue?: boolean;
63
+ }
@@ -0,0 +1,83 @@
1
+ // Adapted from jalcoui (MIT) — github.com/jal-co/ui
2
+
3
+ import type { ColorFormat } from './types';
4
+
5
+ /**
6
+ * Parse a `#rrggbb` / `#rgb` hex string into `{ r, g, b }` (0–255).
7
+ * Returns `null` for malformed input.
8
+ */
9
+ function parseHex(hex: string): { r: number; g: number; b: number } | null {
10
+ const cleaned = hex.trim().replace(/^#/, '');
11
+ if (cleaned.length === 3) {
12
+ const r = parseInt(cleaned[0] + cleaned[0], 16);
13
+ const g = parseInt(cleaned[1] + cleaned[1], 16);
14
+ const b = parseInt(cleaned[2] + cleaned[2], 16);
15
+ if ([r, g, b].some(Number.isNaN)) return null;
16
+ return { r, g, b };
17
+ }
18
+ if (cleaned.length === 6) {
19
+ const r = parseInt(cleaned.slice(0, 2), 16);
20
+ const g = parseInt(cleaned.slice(2, 4), 16);
21
+ const b = parseInt(cleaned.slice(4, 6), 16);
22
+ if ([r, g, b].some(Number.isNaN)) return null;
23
+ return { r, g, b };
24
+ }
25
+ return null;
26
+ }
27
+
28
+ function rgbToHsl(
29
+ r: number,
30
+ g: number,
31
+ b: number,
32
+ ): { h: number; s: number; l: number } {
33
+ const rn = r / 255;
34
+ const gn = g / 255;
35
+ const bn = b / 255;
36
+ const max = Math.max(rn, gn, bn);
37
+ const min = Math.min(rn, gn, bn);
38
+ const l = (max + min) / 2;
39
+ let h = 0;
40
+ let s = 0;
41
+ if (max !== min) {
42
+ const d = max - min;
43
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
44
+ switch (max) {
45
+ case rn:
46
+ h = (gn - bn) / d + (gn < bn ? 6 : 0);
47
+ break;
48
+ case gn:
49
+ h = (bn - rn) / d + 2;
50
+ break;
51
+ case bn:
52
+ h = (rn - gn) / d + 4;
53
+ break;
54
+ }
55
+ h /= 6;
56
+ }
57
+ return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };
58
+ }
59
+
60
+ /**
61
+ * Format a hex color into the requested {@link ColorFormat}. Falls
62
+ * back to the original string when the hex is unparseable.
63
+ */
64
+ export function formatColor(hex: string, format: ColorFormat): string {
65
+ if (format === 'hex') return hex.toLowerCase();
66
+ const rgb = parseHex(hex);
67
+ if (!rgb) return hex;
68
+ if (format === 'rgb') return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
69
+ const { h, s, l } = rgbToHsl(rgb.r, rgb.g, rgb.b);
70
+ return `hsl(${h}, ${s}%, ${l}%)`;
71
+ }
72
+
73
+ /**
74
+ * Return `'light'` when the hex color is bright enough that black
75
+ * text reads better against it, otherwise `'dark'`. Uses standard
76
+ * Rec. 601 luminance (`0.299·R + 0.587·G + 0.114·B`).
77
+ */
78
+ export function getReadableContrast(hex: string): 'light' | 'dark' {
79
+ const rgb = parseHex(hex);
80
+ if (!rgb) return 'dark';
81
+ const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
82
+ return luminance > 0.6 ? 'light' : 'dark';
83
+ }
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { createLazyComponent } from '../../../components/lazy-wrapper';
3
+ import { createLazyComponent } from '../../../../common/lazy-wrapper';
4
4
  import type { ColorPickerProps } from './types';
5
5
 
6
6
  export const LazyColorPicker = createLazyComponent<ColorPickerProps>(
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import type { TreeNode, TreeRowSlot } from '../../data/Tree/types';
3
+ import type { TreeNode, TreeRowSlot } from '../../../data/Tree/types';
4
4
  import { FileIcon, type FileIconSize } from './FileIcon';
5
5
  import type { FolderIconOverrides } from './specialFolders';
6
6
 
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { createLazyComponent } from '../../../components/lazy-wrapper';
3
+ import { createLazyComponent } from '../../../../common/lazy-wrapper';
4
4
  import type { FpsProps } from './types';
5
5
 
6
6
  export const LazyFps = createLazyComponent<FpsProps>(
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { createLazyComponent } from '../../../components/lazy-wrapper';
3
+ import { createLazyComponent } from '../../../../common/lazy-wrapper';
4
4
  import type { RatingProps } from './types';
5
5
 
6
6
  export const LazyRating = createLazyComponent<RatingProps>(
@@ -0,0 +1,28 @@
1
+ # StatusIndicator
2
+
3
+ Compact operational-status pill (dot + label). Maps `Status` → semantic `StatusTone` (success / warning / destructive / info / muted) via `STATUS_CONFIG`.
4
+
5
+ This component is the **golden sample** for the jalcoui port — it demonstrates all CONTRACT rules (semantic tokens, CVA variants, no nested providers, attribution).
6
+
7
+ ```tsx
8
+ import { StatusIndicator } from '@djangocfg/ui-tools/status-indicator';
9
+
10
+ <StatusIndicator status="operational" />
11
+ <StatusIndicator status="degraded" size="lg" />
12
+ <StatusIndicator status="incident" label="Custom label" />
13
+ ```
14
+
15
+ ## Props
16
+
17
+ | Prop | Type | Default | Description |
18
+ |---|---|---|---|
19
+ | `status` | `Status` | — | `'operational' \| 'degraded' \| 'partial-outage' \| 'major-outage' \| 'maintenance' \| 'incident' \| 'unknown'`. |
20
+ | `tone` | `StatusTone` | from `STATUS_CONFIG` | Override the semantic tone. |
21
+ | `label` | `string` | from `STATUS_CONFIG` | Override the visible label. |
22
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Pill scale. |
23
+
24
+ Storybook: `apps/storybook/stories/ui-tools/visual/StatusIndicator.stories.tsx`
25
+
26
+ ---
27
+
28
+ Adapted from jalcoui (MIT).