@djangocfg/ui-tools 2.1.407 → 2.1.409

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 (297) hide show
  1. package/README.md +9 -10
  2. package/dist/file-icon/index.cjs +449 -61
  3. package/dist/file-icon/index.cjs.map +1 -1
  4. package/dist/file-icon/index.d.cts +56 -18
  5. package/dist/file-icon/index.d.ts +56 -18
  6. package/dist/file-icon/index.mjs +448 -62
  7. package/dist/file-icon/index.mjs.map +1 -1
  8. package/dist/tree/index.cjs +49 -22
  9. package/dist/tree/index.cjs.map +1 -1
  10. package/dist/tree/index.d.cts +9 -3
  11. package/dist/tree/index.d.ts +9 -3
  12. package/dist/tree/index.mjs +49 -22
  13. package/dist/tree/index.mjs.map +1 -1
  14. package/dist/{types-B_zhyAqR.d.cts → types-eEu8SeiQ.d.cts} +4 -0
  15. package/dist/{types-B_zhyAqR.d.ts → types-eEu8SeiQ.d.ts} +4 -0
  16. package/package.json +8 -13
  17. package/src/components/FloatingToolbar/index.tsx +37 -3
  18. package/src/lib/page-snapshot/__tests__/capture-integration.test.ts +85 -0
  19. package/src/lib/page-snapshot/__tests__/engine.test.ts +36 -0
  20. package/src/lib/page-snapshot/__tests__/redaction-integration.test.ts +99 -0
  21. package/src/lib/page-snapshot/__tests__/tokens.test.ts +17 -0
  22. package/src/lib/page-snapshot/capture/__tests__/budget.test.ts +49 -0
  23. package/src/lib/page-snapshot/capture/__tests__/chrome-filter.test.ts +47 -0
  24. package/src/lib/page-snapshot/capture/__tests__/fold.test.ts +66 -0
  25. package/src/lib/page-snapshot/capture/__tests__/scope.test.ts +74 -0
  26. package/src/lib/page-snapshot/capture/__tests__/walk.test.ts +129 -0
  27. package/src/lib/page-snapshot/capture/accessible-name.ts +73 -0
  28. package/src/lib/page-snapshot/capture/budget.ts +95 -0
  29. package/src/lib/page-snapshot/capture/chrome-filter.ts +81 -0
  30. package/src/lib/page-snapshot/capture/classify.ts +111 -0
  31. package/src/lib/page-snapshot/capture/dom-utils.ts +111 -0
  32. package/src/lib/page-snapshot/capture/fold.ts +96 -0
  33. package/src/lib/page-snapshot/capture/scope.ts +169 -0
  34. package/src/lib/page-snapshot/capture/walk.ts +250 -0
  35. package/src/lib/page-snapshot/cst/__tests__/serialize.test.ts +50 -0
  36. package/src/lib/page-snapshot/cst/directives.ts +47 -0
  37. package/src/lib/page-snapshot/cst/payload.ts +50 -0
  38. package/src/lib/page-snapshot/cst/serialize.ts +84 -0
  39. package/src/lib/page-snapshot/cst/types.ts +115 -0
  40. package/src/lib/page-snapshot/engine.ts +176 -0
  41. package/src/lib/page-snapshot/index.ts +93 -0
  42. package/src/lib/page-snapshot/react/PageSnapshotChip.tsx +72 -0
  43. package/src/lib/page-snapshot/react/PageSnapshotPreview.tsx +78 -0
  44. package/src/lib/page-snapshot/react/__tests__/PageSnapshotChip.test.tsx +54 -0
  45. package/src/lib/page-snapshot/react/__tests__/provider.test.tsx +103 -0
  46. package/src/lib/page-snapshot/react/__tests__/use-page-snapshot-toggle.test.tsx +62 -0
  47. package/src/lib/page-snapshot/react/provider.tsx +162 -0
  48. package/src/lib/page-snapshot/react/use-page-snapshot-toggle.ts +47 -0
  49. package/src/lib/page-snapshot/react/use-page-snapshot.ts +67 -0
  50. package/src/lib/page-snapshot/redaction/__tests__/audit.test.ts +25 -0
  51. package/src/lib/page-snapshot/redaction/__tests__/heuristics.test.ts +73 -0
  52. package/src/lib/page-snapshot/redaction/__tests__/luhn.test.ts +26 -0
  53. package/src/lib/page-snapshot/redaction/__tests__/patterns.test.ts +60 -0
  54. package/src/lib/page-snapshot/redaction/audit.ts +58 -0
  55. package/src/lib/page-snapshot/redaction/heuristics.ts +75 -0
  56. package/src/lib/page-snapshot/redaction/index.ts +75 -0
  57. package/src/lib/page-snapshot/redaction/luhn.ts +25 -0
  58. package/src/lib/page-snapshot/redaction/patterns.ts +111 -0
  59. package/src/lib/page-snapshot/refs/__tests__/registry.test.ts +24 -0
  60. package/src/lib/page-snapshot/refs/registry.ts +46 -0
  61. package/src/lib/page-snapshot/staleness/__tests__/hash.test.ts +34 -0
  62. package/src/lib/page-snapshot/staleness/hash.ts +20 -0
  63. package/src/lib/page-snapshot/tokens.ts +15 -0
  64. package/src/tools/AudioPlayer/context/PlayerProvider.tsx +13 -14
  65. package/src/tools/AudioPlayer/hooks/useAudioElementEvents.ts +55 -6
  66. package/src/tools/AudioPlayer/parts/Meta/TimeDisplay.tsx +2 -5
  67. package/src/tools/Chat/README.md +277 -39
  68. package/src/tools/Chat/composer/Composer.tsx +471 -0
  69. package/src/tools/Chat/composer/ComposerActionBar.tsx +65 -0
  70. package/src/tools/Chat/composer/ComposerBanner.tsx +128 -0
  71. package/src/tools/Chat/composer/ComposerButton.tsx +64 -0
  72. package/src/tools/Chat/composer/ComposerFooter.tsx +90 -0
  73. package/src/tools/Chat/composer/ComposerMenuButton.tsx +62 -0
  74. package/src/tools/Chat/composer/ComposerModelPicker.tsx +104 -0
  75. package/src/tools/Chat/composer/ComposerRichTextarea.tsx +88 -0
  76. package/src/tools/Chat/composer/ComposerToolPill.tsx +95 -0
  77. package/src/tools/Chat/composer/index.ts +45 -0
  78. package/src/tools/Chat/composer/size-context.tsx +26 -0
  79. package/src/tools/Chat/composer/types.ts +143 -0
  80. package/src/tools/Chat/composer/useComposerActions.tsx +164 -0
  81. package/src/tools/Chat/context/ChatProvider.tsx +54 -3
  82. package/src/tools/Chat/core/__tests__/metadata.test.ts +69 -0
  83. package/src/tools/Chat/core/index.ts +23 -1
  84. package/src/tools/Chat/core/markdown.ts +1 -1
  85. package/src/tools/Chat/core/metadata.ts +47 -0
  86. package/src/tools/Chat/core/payload-dispatch.ts +1 -1
  87. package/src/tools/Chat/core/transport/http.ts +71 -32
  88. package/src/tools/Chat/core/transport/sse.ts +18 -10
  89. package/src/tools/Chat/highlight/HighlightOverlay.tsx +101 -0
  90. package/src/tools/Chat/highlight/README.md +103 -0
  91. package/src/tools/Chat/highlight/SpotlightCanvas.tsx +153 -0
  92. package/src/tools/Chat/highlight/__tests__/HighlightOverlay.test.tsx +112 -0
  93. package/src/tools/Chat/highlight/__tests__/resolveRef.test.ts +55 -0
  94. package/src/tools/Chat/highlight/index.ts +21 -0
  95. package/src/tools/Chat/highlight/resolveRef.ts +42 -0
  96. package/src/tools/Chat/highlight/types.ts +49 -0
  97. package/src/tools/Chat/highlight/useHighlightTargets.ts +128 -0
  98. package/src/tools/Chat/hooks/index.ts +0 -5
  99. package/src/tools/Chat/hooks/useAutoFocusOnStreamEnd.ts +28 -47
  100. package/src/tools/Chat/hooks/useChat.ts +47 -14
  101. package/src/tools/Chat/hooks/useChatComposer.ts +2 -2
  102. package/src/tools/Chat/hooks/useChatLayout.ts +1 -1
  103. package/src/tools/Chat/hooks/useStreamEndFocus.ts +54 -0
  104. package/src/tools/Chat/index.ts +25 -219
  105. package/src/tools/Chat/launcher/ChatDock.tsx +1 -1
  106. package/src/tools/Chat/launcher/ChatLauncher.tsx +1 -1
  107. package/src/tools/Chat/launcher/{ChatHeader.tsx → header/ChatHeader.tsx} +24 -11
  108. package/src/tools/Chat/launcher/{ChatHeaderActionButton.tsx → header/ChatHeaderActionButton.tsx} +34 -3
  109. package/src/tools/Chat/launcher/{ChatHeaderLanguageButton.tsx → header/ChatHeaderLanguageButton.tsx} +2 -2
  110. package/src/tools/Chat/launcher/{ChatHeaderModeToggle.tsx → header/ChatHeaderModeToggle.tsx} +1 -1
  111. package/src/tools/Chat/launcher/{ChatHeaderResetButton.tsx → header/ChatHeaderResetButton.tsx} +2 -1
  112. package/src/tools/Chat/launcher/{HeaderSlots.tsx → header/HeaderSlots.tsx} +3 -3
  113. package/src/tools/Chat/launcher/header/index.ts +26 -0
  114. package/src/tools/Chat/launcher/index.ts +3 -10
  115. package/src/tools/Chat/lazy.tsx +38 -284
  116. package/src/tools/Chat/{components → messages}/MessageBubble.tsx +58 -5
  117. package/src/tools/Chat/{components → messages}/MessageList.tsx +8 -25
  118. package/src/tools/Chat/messages/blocks/MessageBlocks.tsx +131 -0
  119. package/src/tools/Chat/messages/blocks/builtin.tsx +91 -0
  120. package/src/tools/Chat/messages/blocks/index.ts +12 -0
  121. package/src/tools/Chat/messages/blocks/registry.tsx +42 -0
  122. package/src/tools/Chat/messages/blocks/renderers/AudioBlock.tsx +20 -0
  123. package/src/tools/Chat/messages/blocks/renderers/CodeBlock.tsx +19 -0
  124. package/src/tools/Chat/messages/blocks/renderers/GalleryBlock.tsx +26 -0
  125. package/src/tools/Chat/messages/blocks/renderers/ImageBlock.tsx +27 -0
  126. package/src/tools/Chat/messages/blocks/renderers/JsonBlock.tsx +12 -0
  127. package/src/tools/Chat/messages/blocks/renderers/LottieBlock.tsx +11 -0
  128. package/src/tools/Chat/messages/blocks/renderers/MapBlock.tsx +36 -0
  129. package/src/tools/Chat/messages/blocks/renderers/MermaidBlock.tsx +11 -0
  130. package/src/tools/Chat/messages/blocks/renderers/VideoBlock.tsx +24 -0
  131. package/src/tools/Chat/messages/blocks/renderers/types.ts +8 -0
  132. package/src/tools/Chat/{components → messages}/index.ts +11 -5
  133. package/src/tools/Chat/public.ts +212 -0
  134. package/src/tools/Chat/shell/ChatRoot.tsx +345 -0
  135. package/src/tools/Chat/{components → shell}/EmptyState.tsx +4 -2
  136. package/src/tools/Chat/shell/index.ts +15 -0
  137. package/src/tools/Chat/types/block.ts +120 -0
  138. package/src/tools/Chat/types/config.ts +0 -5
  139. package/src/tools/Chat/types/index.ts +17 -0
  140. package/src/tools/Chat/types/message.ts +3 -0
  141. package/src/tools/Chat/utils/index.ts +4 -0
  142. package/src/tools/CodeEditor/README.md +4 -6
  143. package/src/tools/CodeEditor/components/DiffEditor.tsx +48 -13
  144. package/src/tools/CodeEditor/components/Editor.tsx +96 -44
  145. package/src/tools/CodeEditor/context/EditorProvider.tsx +34 -17
  146. package/src/tools/CodeEditor/hooks/useEditorTheme.ts +92 -99
  147. package/src/tools/CodeEditor/hooks/useMonaco.ts +37 -22
  148. package/src/tools/CodeEditor/lazy.tsx +6 -0
  149. package/src/tools/CodeEditor/lib/index.ts +1 -1
  150. package/src/tools/CodeEditor/lib/themes.ts +3 -39
  151. package/src/tools/CronScheduler/CronScheduler.client.tsx +230 -61
  152. package/src/tools/CronScheduler/components/CustomInput.tsx +21 -4
  153. package/src/tools/CronScheduler/components/DayChips.tsx +13 -11
  154. package/src/tools/CronScheduler/components/MonthDayGrid.tsx +4 -4
  155. package/src/tools/CronScheduler/components/SchedulePreview.tsx +7 -3
  156. package/src/tools/CronScheduler/components/TimeSelector.tsx +1 -1
  157. package/src/tools/CronScheduler/index.tsx +1 -1
  158. package/src/tools/CronScheduler/types/index.ts +8 -3
  159. package/src/tools/CronScheduler/utils/cron-humanize.ts +61 -16
  160. package/src/tools/CronScheduler/utils/cron-parser.ts +13 -4
  161. package/src/tools/FileIcon/FileIcon.tsx +24 -39
  162. package/src/tools/FileIcon/get-file-icon.ts +73 -0
  163. package/src/tools/FileIcon/icons/icon-data.ts +399 -0
  164. package/src/tools/FileIcon/index.ts +4 -0
  165. package/src/tools/FileIcon/loader.ts +17 -35
  166. package/src/tools/FileIcon/specialFolders.ts +18 -0
  167. package/src/tools/Gallery/components/lightbox/GalleryLightbox.tsx +112 -35
  168. package/src/tools/Gallery/components/media/GalleryVideo.tsx +21 -2
  169. package/src/tools/Gallery/components/preview/GalleryCarousel.tsx +11 -1
  170. package/src/tools/Gallery/hooks/usePreloadImages.ts +54 -7
  171. package/src/tools/ImageViewer/components/ImageInfo.tsx +12 -1
  172. package/src/tools/ImageViewer/components/ImageToolbar.tsx +51 -43
  173. package/src/tools/ImageViewer/components/ImageViewer.tsx +96 -24
  174. package/src/tools/ImageViewer/hooks/useImageLoading.ts +13 -0
  175. package/src/tools/ImageViewer/utils/constants.ts +3 -0
  176. package/src/tools/ImageViewer/utils/index.ts +1 -0
  177. package/src/tools/JsonForm/JsonSchemaForm.tsx +4 -1
  178. package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +5 -3
  179. package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +7 -4
  180. package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +3 -1
  181. package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +23 -3
  182. package/src/tools/JsonForm/widgets/ColorWidget.tsx +20 -12
  183. package/src/tools/JsonForm/widgets/NumberWidget.tsx +14 -9
  184. package/src/tools/JsonForm/widgets/RadioWidget.tsx +78 -0
  185. package/src/tools/JsonForm/widgets/SelectWidget.tsx +1 -0
  186. package/src/tools/JsonForm/widgets/SliderWidget.tsx +7 -4
  187. package/src/tools/JsonForm/widgets/TextWidget.tsx +41 -17
  188. package/src/tools/JsonForm/widgets/index.ts +1 -0
  189. package/src/tools/JsonTree/components/JsonContent.tsx +115 -40
  190. package/src/tools/LottiePlayer/LottiePlayer.client.tsx +177 -72
  191. package/src/tools/LottiePlayer/index.tsx +14 -4
  192. package/src/tools/LottiePlayer/lazy.tsx +11 -3
  193. package/src/tools/LottiePlayer/types.ts +31 -1
  194. package/src/tools/LottiePlayer/useLottie.ts +32 -9
  195. package/src/tools/LottiePlayer/usePrefersReducedMotion.ts +46 -0
  196. package/src/tools/Map/components/LayerSwitcher.tsx +54 -21
  197. package/src/tools/Map/components/MapCluster.tsx +28 -21
  198. package/src/tools/Map/components/MapContainer.tsx +11 -4
  199. package/src/tools/Map/components/MapLegend.tsx +46 -15
  200. package/src/tools/Map/components/MapMarker.tsx +31 -2
  201. package/src/tools/Map/hooks/useMapEvents.ts +64 -105
  202. package/src/tools/MarkdownEditor/MarkdownEditor.tsx +61 -6
  203. package/src/tools/MarkdownEditor/MentionList.tsx +37 -4
  204. package/src/tools/MarkdownEditor/createMentionSuggestion.ts +11 -0
  205. package/src/tools/MarkdownEditor/lazy.tsx +32 -7
  206. package/src/tools/MarkdownEditor/styles.css +13 -0
  207. package/src/tools/MarkdownMessage/CodeBlock.tsx +40 -17
  208. package/src/tools/MarkdownMessage/MarkdownMessage.tsx +26 -6
  209. package/src/tools/MarkdownMessage/components.tsx +22 -9
  210. package/src/tools/MarkdownMessage/types.ts +24 -1
  211. package/src/tools/Mermaid/Mermaid.client.tsx +27 -5
  212. package/src/tools/Mermaid/components/MermaidErrorPanel.tsx +31 -0
  213. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +14 -17
  214. package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +264 -168
  215. package/src/tools/Mermaid/hooks/useMermaidValidation.ts +76 -10
  216. package/src/tools/Mermaid/index.tsx +6 -0
  217. package/src/tools/Mermaid/utils/mermaid-helpers.ts +141 -18
  218. package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/FieldRow.tsx +11 -1
  219. package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts +49 -20
  220. package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/index.tsx +7 -0
  221. package/src/tools/OpenapiViewer/components/DocsLayout/grouping.ts +7 -4
  222. package/src/tools/OpenapiViewer/constants.ts +3 -0
  223. package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +73 -11
  224. package/src/tools/OpenapiViewer/utils/schemaExport.ts +26 -6
  225. package/src/tools/PrettyCode/PrettyCode.client.tsx +23 -16
  226. package/src/tools/PrettyCode/lazy.tsx +1 -1
  227. package/src/tools/SpeechRecognition/README.md +1 -1
  228. package/src/tools/SpeechRecognition/__tests__/language.test.ts +9 -3
  229. package/src/tools/SpeechRecognition/components/RecordingPulse.tsx +59 -0
  230. package/src/tools/SpeechRecognition/components/index.ts +2 -0
  231. package/src/tools/SpeechRecognition/core/engine/external.ts +24 -7
  232. package/src/tools/SpeechRecognition/core/language.ts +23 -6
  233. package/src/tools/SpeechRecognition/hooks/usePushToTalk.ts +36 -5
  234. package/src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts +18 -11
  235. package/src/tools/SpeechRecognition/widgets/VoiceComposerSlot.tsx +94 -26
  236. package/src/tools/SpeechRecognition/widgets/index.ts +1 -1
  237. package/src/tools/Tree/README.md +4 -8
  238. package/src/tools/Tree/TreeRoot.tsx +22 -10
  239. package/src/tools/Tree/components/TreeContent.tsx +24 -4
  240. package/src/tools/Tree/components/TreeLabel.tsx +8 -2
  241. package/src/tools/Tree/components/TreeRow.tsx +16 -6
  242. package/src/tools/Tree/data/flatten.ts +10 -4
  243. package/src/tools/Tree/types.ts +4 -0
  244. package/src/tools/Uploader/components/UploadAddButton.tsx +29 -6
  245. package/src/tools/Uploader/components/UploadDropzone.tsx +63 -7
  246. package/src/tools/Uploader/components/UploadPageDropOverlay.tsx +19 -5
  247. package/src/tools/Uploader/components/UploadPreviewItem.tsx +47 -17
  248. package/src/tools/Uploader/components/UploadPreviewList.tsx +24 -12
  249. package/src/tools/Uploader/utils/formatters.ts +8 -3
  250. package/src/tools/VideoPlayer/canvas/hls-canvas.tsx +1 -0
  251. package/src/tools/VideoPlayer/canvas/{jsx.d.ts → jsx-augmentation.ts} +12 -19
  252. package/src/tools/VideoPlayer/canvas/vimeo-canvas.tsx +1 -0
  253. package/src/tools/VideoPlayer/canvas/youtube-canvas.tsx +1 -0
  254. package/src/tools/VideoPlayer/parts/fullscreen.tsx +1 -1
  255. package/src/tools/VideoPlayer/parts/pip.tsx +1 -1
  256. package/src/tools/VideoPlayer/parts/playback-rate.tsx +1 -1
  257. package/src/tools/VideoPlayer/parts/seek-bar.tsx +2 -2
  258. package/src/tools/VideoPlayer/parts/volume.tsx +2 -2
  259. package/src/tools/index.ts +2 -1
  260. package/src/tools/Chat/components/AudioToggle.tsx +0 -78
  261. package/src/tools/Chat/components/ChatRoot.tsx +0 -305
  262. package/src/tools/Chat/components/Composer.tsx +0 -216
  263. package/src/tools/Chat/hooks/useChatScroll.ts +0 -145
  264. package/src/tools/Chat/types.ts +0 -9
  265. package/src/tools/JsonTree/components/JsonToolbar.tsx +0 -95
  266. package/src/tools/JsonTree/hooks/useElementCorner.ts +0 -84
  267. package/src/tools/JsonTree/hooks/useNavbarHeight.ts +0 -83
  268. package/src/tools/OpenapiViewer/components/DocsLayout/schemaFields.ts +0 -121
  269. package/src/tools/Tour/README.md +0 -373
  270. package/src/tools/Tour/components/Tour.tsx +0 -12
  271. package/src/tools/Tour/components/TourContent.tsx +0 -171
  272. package/src/tools/Tour/components/TourNavigation.tsx +0 -77
  273. package/src/tools/Tour/components/TourProgress.tsx +0 -88
  274. package/src/tools/Tour/components/TourSpotlight.tsx +0 -199
  275. package/src/tools/Tour/components/index.ts +0 -5
  276. package/src/tools/Tour/context/TourContext.ts +0 -19
  277. package/src/tools/Tour/context/TourProvider.tsx +0 -292
  278. package/src/tools/Tour/context/index.ts +0 -2
  279. package/src/tools/Tour/hooks/index.ts +0 -3
  280. package/src/tools/Tour/hooks/useKeyboardNavigation.ts +0 -59
  281. package/src/tools/Tour/hooks/useStepTarget.ts +0 -121
  282. package/src/tools/Tour/hooks/useTour.ts +0 -42
  283. package/src/tools/Tour/index.ts +0 -38
  284. package/src/tools/Tour/types/index.ts +0 -224
  285. package/src/tools/Tour/utils/dom.ts +0 -98
  286. package/src/tools/Tour/utils/index.ts +0 -3
  287. package/src/tools/Tour/utils/logger.ts +0 -3
  288. package/src/tools/Tour/utils/scrollIntoView.ts +0 -24
  289. /package/src/tools/Chat/{config.ts → constants.ts} +0 -0
  290. /package/src/tools/Chat/launcher/{ChatHeaderAudioToggle.tsx → header/ChatHeaderAudioToggle.tsx} +0 -0
  291. /package/src/tools/Chat/{components → messages}/Attachments.tsx +0 -0
  292. /package/src/tools/Chat/{components → messages}/JumpToLatest.tsx +0 -0
  293. /package/src/tools/Chat/{components → messages}/MessageActions.tsx +0 -0
  294. /package/src/tools/Chat/{components → messages}/Sources.tsx +0 -0
  295. /package/src/tools/Chat/{components → messages}/StreamingIndicator.tsx +0 -0
  296. /package/src/tools/Chat/{components → messages}/ToolCalls.tsx +0 -0
  297. /package/src/tools/Chat/{components → shell}/ErrorBanner.tsx +0 -0
@@ -1,121 +0,0 @@
1
- /**
2
- * Flatten a JSON Schema node into a flat list of (name, type, required,
3
- * description) rows, ready to feed into the existing parameter table.
4
- *
5
- * Rules:
6
- * - ``type: object`` → one row per property.
7
- * - ``type: array`` → recurse into items; prefix each row with ``[].``
8
- * so the caller sees "[].username string" etc.
9
- * - Nested objects → dot-joined path: ``category.name``. We expand
10
- * one level; deeper graphs get a single summary
11
- * row ("category.* (object)") to keep the table
12
- * readable.
13
- *
14
- * This is a presentation helper — not a full form generator. It powers
15
- * the read-only fields table shown in the docs longread.
16
- */
17
-
18
- type JsonSchemaNode = Record<string, unknown> & {
19
- type?: string;
20
- properties?: Record<string, JsonSchemaNode>;
21
- required?: string[];
22
- items?: JsonSchemaNode;
23
- enum?: unknown[];
24
- description?: string;
25
- format?: string;
26
- };
27
-
28
- export interface SchemaField {
29
- name: string;
30
- type: string;
31
- required: boolean;
32
- description?: string;
33
- }
34
-
35
- const MAX_DEPTH = 2;
36
-
37
- function describeType(node: JsonSchemaNode): string {
38
- if (!node.type && node.properties) return 'object';
39
- const base = node.type || 'any';
40
- if (base === 'array') {
41
- const itemType = node.items ? describeType(node.items) : 'any';
42
- return `array<${itemType}>`;
43
- }
44
- if (Array.isArray(node.enum) && node.enum.length > 0) {
45
- return `${base} enum`;
46
- }
47
- if (node.format) return `${base} (${node.format})`;
48
- return base;
49
- }
50
-
51
- export function schemaToFields(
52
- schema: JsonSchemaNode | undefined,
53
- prefix = '',
54
- depth = 0,
55
- ): SchemaField[] {
56
- if (!schema || depth > MAX_DEPTH) return [];
57
-
58
- // Unwrap arrays: show the inner item's fields, prefixed with ``[]``.
59
- if (schema.type === 'array') {
60
- if (!schema.items) {
61
- return [{ name: prefix || '[]', type: 'array', required: false }];
62
- }
63
- const inner = schemaToFields(schema.items, prefix ? `${prefix}[]` : '[]', depth);
64
- if (inner.length === 0) {
65
- return [
66
- {
67
- name: prefix || '[]',
68
- type: describeType(schema),
69
- required: false,
70
- description: schema.description,
71
- },
72
- ];
73
- }
74
- return inner;
75
- }
76
-
77
- // Primitives and unknown — single row.
78
- if (schema.type !== 'object' && !schema.properties) {
79
- return [
80
- {
81
- name: prefix || '(body)',
82
- type: describeType(schema),
83
- required: false,
84
- description: schema.description,
85
- },
86
- ];
87
- }
88
-
89
- // Objects — one row per property, recurse for nested objects/arrays.
90
- const required = new Set(schema.required ?? []);
91
- const rows: SchemaField[] = [];
92
- const props = schema.properties ?? {};
93
- for (const [key, node] of Object.entries(props)) {
94
- const fullName = prefix ? `${prefix}.${key}` : key;
95
- const isRequired = required.has(key);
96
-
97
- const isNestedExpandable =
98
- (node.type === 'object' && node.properties) ||
99
- (node.type === 'array' && node.items);
100
-
101
- if (isNestedExpandable && depth < MAX_DEPTH) {
102
- // Leaf summary row for the parent itself (so the user sees
103
- // its description) + recurse for inner fields.
104
- rows.push({
105
- name: fullName,
106
- type: describeType(node),
107
- required: isRequired,
108
- description: node.description,
109
- });
110
- rows.push(...schemaToFields(node, fullName, depth + 1));
111
- } else {
112
- rows.push({
113
- name: fullName,
114
- type: describeType(node),
115
- required: isRequired,
116
- description: node.description,
117
- });
118
- }
119
- }
120
- return rows;
121
- }
@@ -1,373 +0,0 @@
1
- # Tour
2
-
3
- Smart, decomposed onboarding Tour component with spotlight highlighting, animations, and i18n support.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- pnpm add @djangocfg/ui-tools
9
- ```
10
-
11
- ## Basic Usage
12
-
13
- ```tsx
14
- import { Tour, useTour } from '@djangocfg/ui-tools/tour';
15
-
16
- const tours = [
17
- {
18
- id: 'onboarding',
19
- steps: [
20
- {
21
- id: 'welcome',
22
- target: '[data-tour-step-id="header"]',
23
- title: 'Welcome',
24
- content: 'Let us show you around!',
25
- position: 'bottom',
26
- },
27
- {
28
- id: 'sidebar',
29
- target: '#sidebar',
30
- title: 'Navigation',
31
- content: 'Use the sidebar to navigate.',
32
- position: 'right',
33
- },
34
- ],
35
- },
36
- ];
37
-
38
- function App() {
39
- return (
40
- <Tour
41
- tours={tours}
42
- onComplete={(tourId) => console.log('Tour completed:', tourId)}
43
- >
44
- <Layout />
45
- </Tour>
46
- );
47
- }
48
-
49
- function StartButton() {
50
- const { start } = useTour();
51
- return <button onClick={() => start('onboarding')}>Start Tour</button>;
52
- }
53
- ```
54
-
55
- ## Components
56
-
57
- ### Tour
58
-
59
- All-in-one wrapper combining TourProvider with overlay rendering.
60
-
61
- ```tsx
62
- <Tour
63
- tours={tours} // Array of tour configs
64
- spotlight={true} // Enable spotlight (default: true)
65
- spotlightOpacity={0.5} // Overlay opacity (default: 0.5)
66
- spotlightBlur={0} // Backdrop blur in px (default: 0)
67
- animated={true} // Enable animations (default: true)
68
- pulseRing={false} // Pulsing ring around target (default: false)
69
- showArrow={false} // Show arrow to target (default: false)
70
- keyboardNavigation={true} // Arrow keys navigation (default: true)
71
- closeOnEscape={true} // Close on Escape (default: true)
72
- closeOnOverlayClick={false} // Close on overlay click (default: false)
73
- scrollToTarget={true} // Scroll target into view (default: true)
74
- progressVariant="dots" // 'dots' | 'bar' | 'fraction' | 'none'
75
- showSkipButton={true} // Show skip button (default: true)
76
- onStart={(tourId) => {}}
77
- onComplete={(tourId) => {}}
78
- onSkip={(tourId, stepIndex) => {}}
79
- onStepChange={(index, step, direction) => {}}
80
- >
81
- {children}
82
- </Tour>
83
- ```
84
-
85
- ### Custom Composition
86
-
87
- ```tsx
88
- import {
89
- TourProvider,
90
- TourSpotlight,
91
- TourContent,
92
- TourProgress,
93
- TourNavigation,
94
- useTour,
95
- } from '@djangocfg/ui-tools/tour';
96
-
97
- function CustomTourOverlay() {
98
- const { currentStep, currentStepIndex, totalSteps, next, previous, close } = useTour();
99
- // ... render custom UI
100
- }
101
-
102
- <TourProvider tours={tours}>
103
- <App />
104
- <CustomTourOverlay />
105
- </TourProvider>
106
- ```
107
-
108
- ## Step Configuration
109
-
110
- ```tsx
111
- interface TourStep {
112
- id: string; // Unique identifier
113
- target?: string; // CSS selector or data-tour-step-id
114
- title: ReactNode; // Step title
115
- content: ReactNode; // Step content
116
- position?: 'top' | 'bottom' | 'left' | 'right' | 'auto';
117
- offset?: number; // Popover offset (default: 12)
118
- align?: 'start' | 'center' | 'end';
119
-
120
- // Multi-page tours
121
- nextRoute?: string; // Navigate on Next
122
- previousRoute?: string; // Navigate on Previous
123
-
124
- // Labels (overrides i18n)
125
- nextLabel?: ReactNode;
126
- previousLabel?: ReactNode;
127
-
128
- // Spotlight
129
- disableSpotlight?: boolean;
130
- spotlightPadding?: number; // Padding around target (default: 8)
131
- spotlightRadius?: number; // Border radius (default: 4)
132
- allowTargetInteraction?: boolean;
133
-
134
- // Auto-advance
135
- autoAdvance?: number; // Auto-advance after ms
136
-
137
- // Custom actions
138
- actions?: TourAction[];
139
-
140
- // Callbacks
141
- onBeforeShow?: () => boolean | Promise<boolean>;
142
- onShow?: () => void;
143
- onHide?: () => void;
144
- }
145
- ```
146
-
147
- ## Targeting Elements
148
-
149
- ### Option 1: CSS Selector
150
-
151
- ```tsx
152
- {
153
- id: 'step-1',
154
- target: '#my-button', // or '.my-class', '[data-id="123"]'
155
- title: 'Click here',
156
- content: '...',
157
- }
158
- ```
159
-
160
- ### Option 2: data-tour-step-id Attribute
161
-
162
- ```tsx
163
- // In your component
164
- <header data-tour-step-id="header">...</header>
165
-
166
- // In tour config
167
- {
168
- id: 'header', // matches data-tour-step-id
169
- title: 'Welcome',
170
- content: '...',
171
- }
172
- ```
173
-
174
- ## Hooks
175
-
176
- ### useTour
177
-
178
- ```tsx
179
- const {
180
- start, // (tourId, startIndex?) => void
181
- next, // () => void
182
- previous, // () => void
183
- goTo, // (index) => void
184
- close, // () => void
185
- isActive, // boolean
186
- activeTourId, // string | null
187
- currentStep, // TourStep | null
188
- currentStepIndex,// number
189
- totalSteps, // number
190
- isFirstStep, // boolean
191
- isLastStep, // boolean
192
- progress, // number (0-1)
193
- } = useTour();
194
- ```
195
-
196
- ## Keyboard Navigation
197
-
198
- When enabled (default):
199
- - `ArrowRight` / `ArrowDown`: Next step
200
- - `ArrowLeft` / `ArrowUp`: Previous step
201
- - `Escape`: Close tour
202
-
203
- ## Multi-page Tours
204
-
205
- ```tsx
206
- const tours = [{
207
- id: 'walkthrough',
208
- steps: [
209
- {
210
- id: 'home',
211
- target: '#hero',
212
- title: 'Welcome',
213
- content: 'Start here.',
214
- nextRoute: '/dashboard', // Navigate on Next
215
- },
216
- {
217
- id: 'dashboard',
218
- target: '#stats',
219
- title: 'Dashboard',
220
- content: 'View your metrics.',
221
- previousRoute: '/', // Navigate on Previous
222
- },
223
- ],
224
- }];
225
- ```
226
-
227
- ## Callbacks
228
-
229
- ```tsx
230
- <Tour
231
- tours={tours}
232
- onStart={(tourId) => {
233
- analytics.track('tour_started', { tourId });
234
- }}
235
- onComplete={(tourId) => {
236
- localStorage.setItem(`tour_${tourId}_completed`, 'true');
237
- }}
238
- onSkip={(tourId, stepIndex) => {
239
- analytics.track('tour_skipped', { tourId, stepIndex });
240
- }}
241
- onStepChange={(index, step, direction) => {
242
- analytics.track('tour_step', { stepId: step.id, direction });
243
- }}
244
- onBeforeStepChange={async (currentIndex, nextIndex) => {
245
- // Return false to prevent navigation
246
- return true;
247
- }}
248
- >
249
- ```
250
-
251
- ## Progress Variants
252
-
253
- - `dots` - Clickable dots (default)
254
- - `bar` - Progress bar
255
- - `fraction` - "1 / 5" text
256
- - `none` - No progress indicator
257
-
258
- ## Visual Options
259
-
260
- ### Arrow
261
-
262
- Shows an arrow pointing from the popover to the target element:
263
-
264
- ```tsx
265
- <Tour tours={tours} showArrow>
266
- {children}
267
- </Tour>
268
- ```
269
-
270
- ### Backdrop Blur
271
-
272
- Blurs the background outside the spotlight for enhanced focus:
273
-
274
- ```tsx
275
- <Tour tours={tours} spotlightBlur={4} spotlightOpacity={0.3}>
276
- {children}
277
- </Tour>
278
- ```
279
-
280
- ### Pulse Ring
281
-
282
- Animated pulsing ring around the target to draw attention:
283
-
284
- ```tsx
285
- <Tour tours={tours} pulseRing>
286
- {children}
287
- </Tour>
288
- ```
289
-
290
- ### Disable Animations
291
-
292
- Turn off all spotlight transition animations:
293
-
294
- ```tsx
295
- <Tour tours={tours} animated={false}>
296
- {children}
297
- </Tour>
298
- ```
299
-
300
- ### Full Featured
301
-
302
- Combine all visual enhancements:
303
-
304
- ```tsx
305
- <Tour
306
- tours={tours}
307
- showArrow
308
- spotlightBlur={2}
309
- spotlightOpacity={0.4}
310
- pulseRing
311
- >
312
- {children}
313
- </Tour>
314
- ```
315
-
316
- ## Internationalization (i18n)
317
-
318
- Tour uses `@djangocfg/i18n` for translations. Default labels come from `tools.tour.*` keys:
319
-
320
- - `tools.tour.next` - "Next"
321
- - `tools.tour.previous` - "Back"
322
- - `tools.tour.skip` - "Skip"
323
- - `tools.tour.finish` - "Finish"
324
- - `tools.tour.close` - "Close"
325
- - `tools.tour.stepOf` - "Step {current} of {total}"
326
-
327
- To customize, either:
328
-
329
- 1. **Override via props** (per-step or global):
330
- ```tsx
331
- <Tour
332
- tours={tours}
333
- skipLabel="Exit tour"
334
- finishLabel="Done!"
335
- >
336
- ```
337
-
338
- 2. **Provide custom translations** via I18nProvider:
339
- ```tsx
340
- import { I18nProvider, mergeTranslations, en } from '@djangocfg/i18n';
341
-
342
- const customEn = mergeTranslations(en, {
343
- tools: {
344
- tour: {
345
- next: 'Continue',
346
- skip: 'Exit',
347
- }
348
- }
349
- });
350
-
351
- <I18nProvider locale="en" translations={customEn}>
352
- <Tour tours={tours}>
353
- <App />
354
- </Tour>
355
- </I18nProvider>
356
- ```
357
-
358
- ## Features
359
-
360
- - Spotlight highlighting with SVG mask
361
- - Optional backdrop blur for enhanced focus
362
- - Arrow pointing from popover to target
363
- - Smooth animations between steps
364
- - Pulse ring effect for attention
365
- - Keyboard navigation
366
- - Multi-step and multi-page tours
367
- - Progress indicators (dots, bar, fraction)
368
- - Auto-scroll to target
369
- - Lifecycle callbacks
370
- - Custom positioning
371
- - Skip/close functionality
372
- - ARIA accessibility
373
- - Full i18n support
@@ -1,12 +0,0 @@
1
- 'use client';
2
-
3
- import { TourProvider } from '../context/TourProvider';
4
- import type { TourProps } from '../types';
5
-
6
- /**
7
- * All-in-one Tour component.
8
- * Combines TourProvider with children for simple usage.
9
- */
10
- export function Tour({ children, ...providerProps }: TourProps) {
11
- return <TourProvider {...providerProps}>{children}</TourProvider>;
12
- }
@@ -1,171 +0,0 @@
1
- 'use client';
2
-
3
- import { useMemo } from 'react';
4
- import { X } from 'lucide-react';
5
- import { cn } from '@djangocfg/ui-core/lib';
6
- import {
7
- Popover,
8
- PopoverAnchor,
9
- PopoverContent,
10
- PopoverArrow,
11
- Button,
12
- } from '@djangocfg/ui-core/components';
13
- import { TourProgress } from './TourProgress';
14
- import { TourNavigation } from './TourNavigation';
15
- import type { TourContentProps, TourPosition } from '../types';
16
-
17
- /**
18
- * Map TourPosition to Radix Popover side.
19
- */
20
- function mapPositionToSide(
21
- position: TourPosition | undefined
22
- ): 'top' | 'bottom' | 'left' | 'right' {
23
- if (!position || position === 'auto') return 'bottom';
24
- return position;
25
- }
26
-
27
- /**
28
- * Tour step content popover.
29
- * Uses Radix Popover with virtual anchor for positioning.
30
- */
31
- export function TourContent({
32
- step,
33
- targetRect,
34
- currentIndex,
35
- totalSteps,
36
- onNext,
37
- onPrevious,
38
- onClose,
39
- progressVariant = 'dots',
40
- showSkipButton = true,
41
- showArrow = false,
42
- skipLabel,
43
- finishLabel,
44
- onGoTo,
45
- className,
46
- }: TourContentProps) {
47
- // Prepare virtual ref for Popover anchor
48
- const virtualRef = useMemo(
49
- () => ({
50
- current: {
51
- getBoundingClientRect: () => targetRect,
52
- },
53
- }),
54
- [targetRect]
55
- );
56
-
57
- // Prepare positioning
58
- const side = mapPositionToSide(step.position);
59
- const sideOffset = step.offset ?? 12;
60
- const align = step.align ?? 'center';
61
- const alignOffset = step.alignOffset ?? 0;
62
-
63
- // Prepare step state
64
- const isFirstStep = currentIndex === 0;
65
- const isLastStep = currentIndex === totalSteps - 1;
66
-
67
- // Prepare styles
68
- const popoverContentClassName = cn('z-[51] w-72', step.className, className);
69
-
70
- // Prepare custom actions
71
- const hasCustomActions = step.actions && step.actions.length > 0;
72
- const customActions = useMemo(() => {
73
- if (!step.actions) return [];
74
-
75
- return step.actions.map((action, index) => ({
76
- key: index,
77
- label: action.label,
78
- onClick: action.onClick,
79
- className: cn(
80
- 'text-sm font-medium underline-offset-4 hover:underline',
81
- action.variant === 'destructive' && 'text-destructive'
82
- ),
83
- }));
84
- }, [step.actions]);
85
-
86
- // Event handlers
87
- const preventAutoFocus = (e: Event) => e.preventDefault();
88
-
89
- return (
90
- <Popover open>
91
- <PopoverAnchor virtualRef={virtualRef as React.RefObject<Element>} />
92
- <PopoverContent
93
- side={side}
94
- sideOffset={sideOffset}
95
- align={align}
96
- alignOffset={alignOffset}
97
- avoidCollisions
98
- collisionPadding={16}
99
- className={popoverContentClassName}
100
- onOpenAutoFocus={preventAutoFocus}
101
- onCloseAutoFocus={preventAutoFocus}
102
- role="dialog"
103
- aria-labelledby="tour-title"
104
- aria-describedby="tour-description"
105
- >
106
- {showArrow && <PopoverArrow className="fill-popover" />}
107
-
108
- {/* Header with close button */}
109
- <div className="flex items-start justify-between gap-2 pb-2">
110
- <h3 id="tour-title" className="text-base font-semibold leading-none tracking-tight">
111
- {step.title}
112
- </h3>
113
- {showSkipButton && (
114
- <Button
115
- variant="ghost"
116
- size="icon"
117
- className="h-6 w-6 shrink-0 -mt-1 -mr-2"
118
- onClick={onClose}
119
- >
120
- <X className="h-4 w-4" />
121
- </Button>
122
- )}
123
- </div>
124
-
125
- {/* Content */}
126
- <p id="tour-description" className="text-sm text-muted-foreground">
127
- {step.content}
128
- </p>
129
-
130
- {/* Footer */}
131
- <div className="mt-4 flex flex-col gap-3">
132
- <TourProgress
133
- current={currentIndex}
134
- total={totalSteps}
135
- variant={progressVariant}
136
- onDotClick={onGoTo}
137
- />
138
-
139
- <TourNavigation
140
- onNext={onNext}
141
- onPrevious={onPrevious}
142
- isFirstStep={isFirstStep}
143
- isLastStep={isLastStep}
144
- nextLabel={step.nextLabel}
145
- previousLabel={step.previousLabel}
146
- finishLabel={finishLabel}
147
- nextRoute={step.nextRoute}
148
- previousRoute={step.previousRoute}
149
- className="w-full"
150
- />
151
-
152
- {/* Custom actions */}
153
- {hasCustomActions && (
154
- <div className="flex w-full flex-wrap gap-2">
155
- {customActions.map((action) => (
156
- <button
157
- key={action.key}
158
- type="button"
159
- onClick={action.onClick}
160
- className={action.className}
161
- >
162
- {action.label}
163
- </button>
164
- ))}
165
- </div>
166
- )}
167
- </div>
168
- </PopoverContent>
169
- </Popover>
170
- );
171
- }