@djangocfg/ui-tools 2.1.404 → 2.1.408
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.
- package/README.md +9 -11
- package/dist/file-icon/index.cjs +449 -61
- package/dist/file-icon/index.cjs.map +1 -1
- package/dist/file-icon/index.d.cts +56 -18
- package/dist/file-icon/index.d.ts +56 -18
- package/dist/file-icon/index.mjs +448 -62
- package/dist/file-icon/index.mjs.map +1 -1
- package/dist/tree/index.cjs +49 -22
- package/dist/tree/index.cjs.map +1 -1
- package/dist/tree/index.d.cts +9 -3
- package/dist/tree/index.d.ts +9 -3
- package/dist/tree/index.mjs +49 -22
- package/dist/tree/index.mjs.map +1 -1
- package/dist/{types-B_zhyAqR.d.cts → types-eEu8SeiQ.d.cts} +4 -0
- package/dist/{types-B_zhyAqR.d.ts → types-eEu8SeiQ.d.ts} +4 -0
- package/package.json +13 -16
- package/src/components/FloatingToolbar/index.tsx +37 -3
- package/src/lib/page-snapshot/__tests__/capture-integration.test.ts +85 -0
- package/src/lib/page-snapshot/__tests__/engine.test.ts +36 -0
- package/src/lib/page-snapshot/__tests__/redaction-integration.test.ts +99 -0
- package/src/lib/page-snapshot/__tests__/tokens.test.ts +17 -0
- package/src/lib/page-snapshot/capture/__tests__/budget.test.ts +49 -0
- package/src/lib/page-snapshot/capture/__tests__/chrome-filter.test.ts +47 -0
- package/src/lib/page-snapshot/capture/__tests__/fold.test.ts +66 -0
- package/src/lib/page-snapshot/capture/__tests__/scope.test.ts +74 -0
- package/src/lib/page-snapshot/capture/__tests__/walk.test.ts +129 -0
- package/src/lib/page-snapshot/capture/accessible-name.ts +73 -0
- package/src/lib/page-snapshot/capture/budget.ts +95 -0
- package/src/lib/page-snapshot/capture/chrome-filter.ts +81 -0
- package/src/lib/page-snapshot/capture/classify.ts +111 -0
- package/src/lib/page-snapshot/capture/dom-utils.ts +111 -0
- package/src/lib/page-snapshot/capture/fold.ts +96 -0
- package/src/lib/page-snapshot/capture/scope.ts +169 -0
- package/src/lib/page-snapshot/capture/walk.ts +250 -0
- package/src/lib/page-snapshot/cst/__tests__/serialize.test.ts +50 -0
- package/src/lib/page-snapshot/cst/directives.ts +47 -0
- package/src/lib/page-snapshot/cst/payload.ts +50 -0
- package/src/lib/page-snapshot/cst/serialize.ts +84 -0
- package/src/lib/page-snapshot/cst/types.ts +115 -0
- package/src/lib/page-snapshot/engine.ts +176 -0
- package/src/lib/page-snapshot/index.ts +93 -0
- package/src/lib/page-snapshot/react/PageSnapshotChip.tsx +72 -0
- package/src/lib/page-snapshot/react/PageSnapshotPreview.tsx +78 -0
- package/src/lib/page-snapshot/react/__tests__/PageSnapshotChip.test.tsx +54 -0
- package/src/lib/page-snapshot/react/__tests__/provider.test.tsx +103 -0
- package/src/lib/page-snapshot/react/__tests__/use-page-snapshot-toggle.test.tsx +62 -0
- package/src/lib/page-snapshot/react/provider.tsx +162 -0
- package/src/lib/page-snapshot/react/use-page-snapshot-toggle.ts +47 -0
- package/src/lib/page-snapshot/react/use-page-snapshot.ts +67 -0
- package/src/lib/page-snapshot/redaction/__tests__/audit.test.ts +25 -0
- package/src/lib/page-snapshot/redaction/__tests__/heuristics.test.ts +73 -0
- package/src/lib/page-snapshot/redaction/__tests__/luhn.test.ts +26 -0
- package/src/lib/page-snapshot/redaction/__tests__/patterns.test.ts +60 -0
- package/src/lib/page-snapshot/redaction/audit.ts +58 -0
- package/src/lib/page-snapshot/redaction/heuristics.ts +75 -0
- package/src/lib/page-snapshot/redaction/index.ts +75 -0
- package/src/lib/page-snapshot/redaction/luhn.ts +25 -0
- package/src/lib/page-snapshot/redaction/patterns.ts +111 -0
- package/src/lib/page-snapshot/refs/__tests__/registry.test.ts +24 -0
- package/src/lib/page-snapshot/refs/registry.ts +46 -0
- package/src/lib/page-snapshot/staleness/__tests__/hash.test.ts +34 -0
- package/src/lib/page-snapshot/staleness/hash.ts +20 -0
- package/src/lib/page-snapshot/tokens.ts +15 -0
- package/src/tools/AudioPlayer/context/PlayerProvider.tsx +13 -14
- package/src/tools/AudioPlayer/hooks/useAudioElementEvents.ts +55 -6
- package/src/tools/AudioPlayer/lazy.tsx +13 -27
- package/src/tools/AudioPlayer/parts/Meta/TimeDisplay.tsx +2 -5
- package/src/tools/Chat/README.md +267 -39
- package/src/tools/Chat/composer/Composer.tsx +471 -0
- package/src/tools/Chat/composer/ComposerActionBar.tsx +65 -0
- package/src/tools/Chat/composer/ComposerBanner.tsx +128 -0
- package/src/tools/Chat/composer/ComposerButton.tsx +64 -0
- package/src/tools/Chat/composer/ComposerFooter.tsx +90 -0
- package/src/tools/Chat/composer/ComposerMenuButton.tsx +62 -0
- package/src/tools/Chat/composer/ComposerModelPicker.tsx +104 -0
- package/src/tools/Chat/composer/ComposerRichTextarea.tsx +88 -0
- package/src/tools/Chat/composer/ComposerToolPill.tsx +95 -0
- package/src/tools/Chat/composer/index.ts +45 -0
- package/src/tools/Chat/composer/size-context.tsx +26 -0
- package/src/tools/Chat/composer/types.ts +143 -0
- package/src/tools/Chat/composer/useComposerActions.tsx +164 -0
- package/src/tools/Chat/context/ChatProvider.tsx +54 -3
- package/src/tools/Chat/core/__tests__/metadata.test.ts +69 -0
- package/src/tools/Chat/core/index.ts +23 -1
- package/src/tools/Chat/core/markdown.ts +1 -1
- package/src/tools/Chat/core/metadata.ts +47 -0
- package/src/tools/Chat/core/payload-dispatch.ts +1 -1
- package/src/tools/Chat/core/transport/http.ts +71 -32
- package/src/tools/Chat/core/transport/sse.ts +18 -10
- package/src/tools/Chat/highlight/HighlightOverlay.tsx +101 -0
- package/src/tools/Chat/highlight/README.md +103 -0
- package/src/tools/Chat/highlight/SpotlightCanvas.tsx +153 -0
- package/src/tools/Chat/highlight/__tests__/HighlightOverlay.test.tsx +112 -0
- package/src/tools/Chat/highlight/__tests__/resolveRef.test.ts +55 -0
- package/src/tools/Chat/highlight/index.ts +21 -0
- package/src/tools/Chat/highlight/resolveRef.ts +42 -0
- package/src/tools/Chat/highlight/types.ts +49 -0
- package/src/tools/Chat/highlight/useHighlightTargets.ts +128 -0
- package/src/tools/Chat/hooks/index.ts +0 -5
- package/src/tools/Chat/hooks/useAutoFocusOnStreamEnd.ts +28 -47
- package/src/tools/Chat/hooks/useChat.ts +47 -14
- package/src/tools/Chat/hooks/useChatComposer.ts +2 -2
- package/src/tools/Chat/hooks/useChatLayout.ts +1 -1
- package/src/tools/Chat/hooks/useStreamEndFocus.ts +54 -0
- package/src/tools/Chat/index.ts +25 -219
- package/src/tools/Chat/launcher/ChatDock.tsx +1 -1
- package/src/tools/Chat/launcher/ChatLauncher.tsx +1 -1
- package/src/tools/Chat/launcher/{ChatHeader.tsx → header/ChatHeader.tsx} +24 -11
- package/src/tools/Chat/launcher/{ChatHeaderActionButton.tsx → header/ChatHeaderActionButton.tsx} +34 -3
- package/src/tools/Chat/launcher/{ChatHeaderLanguageButton.tsx → header/ChatHeaderLanguageButton.tsx} +2 -2
- package/src/tools/Chat/launcher/{ChatHeaderModeToggle.tsx → header/ChatHeaderModeToggle.tsx} +1 -1
- package/src/tools/Chat/launcher/{ChatHeaderResetButton.tsx → header/ChatHeaderResetButton.tsx} +2 -1
- package/src/tools/Chat/launcher/{HeaderSlots.tsx → header/HeaderSlots.tsx} +3 -3
- package/src/tools/Chat/launcher/header/index.ts +26 -0
- package/src/tools/Chat/launcher/index.ts +3 -10
- package/src/tools/Chat/lazy.tsx +38 -284
- package/src/tools/Chat/{components → messages}/MessageBubble.tsx +58 -5
- package/src/tools/Chat/{components → messages}/MessageList.tsx +8 -25
- package/src/tools/Chat/messages/blocks/MessageBlocks.tsx +131 -0
- package/src/tools/Chat/messages/blocks/builtin.tsx +91 -0
- package/src/tools/Chat/messages/blocks/index.ts +12 -0
- package/src/tools/Chat/messages/blocks/registry.tsx +42 -0
- package/src/tools/Chat/messages/blocks/renderers/AudioBlock.tsx +20 -0
- package/src/tools/Chat/messages/blocks/renderers/CodeBlock.tsx +19 -0
- package/src/tools/Chat/messages/blocks/renderers/GalleryBlock.tsx +26 -0
- package/src/tools/Chat/messages/blocks/renderers/ImageBlock.tsx +27 -0
- package/src/tools/Chat/messages/blocks/renderers/JsonBlock.tsx +12 -0
- package/src/tools/Chat/messages/blocks/renderers/LottieBlock.tsx +11 -0
- package/src/tools/Chat/messages/blocks/renderers/MapBlock.tsx +36 -0
- package/src/tools/Chat/messages/blocks/renderers/MermaidBlock.tsx +11 -0
- package/src/tools/Chat/messages/blocks/renderers/VideoBlock.tsx +24 -0
- package/src/tools/Chat/messages/blocks/renderers/types.ts +8 -0
- package/src/tools/Chat/{components → messages}/index.ts +11 -5
- package/src/tools/Chat/public.ts +212 -0
- package/src/tools/Chat/shell/ChatRoot.tsx +326 -0
- package/src/tools/Chat/{components → shell}/EmptyState.tsx +4 -2
- package/src/tools/Chat/shell/index.ts +15 -0
- package/src/tools/Chat/types/block.ts +120 -0
- package/src/tools/Chat/types/config.ts +0 -5
- package/src/tools/Chat/types/index.ts +17 -0
- package/src/tools/Chat/types/message.ts +3 -0
- package/src/tools/Chat/utils/index.ts +4 -0
- package/src/tools/CodeEditor/README.md +4 -6
- package/src/tools/CodeEditor/components/DiffEditor.tsx +48 -13
- package/src/tools/CodeEditor/components/Editor.tsx +96 -44
- package/src/tools/CodeEditor/context/EditorProvider.tsx +34 -17
- package/src/tools/CodeEditor/hooks/useEditorTheme.ts +92 -99
- package/src/tools/CodeEditor/hooks/useMonaco.ts +37 -22
- package/src/tools/CodeEditor/lazy.tsx +6 -0
- package/src/tools/CodeEditor/lib/index.ts +1 -1
- package/src/tools/CodeEditor/lib/themes.ts +3 -39
- package/src/tools/CronScheduler/CronScheduler.client.tsx +230 -61
- package/src/tools/CronScheduler/components/CustomInput.tsx +21 -4
- package/src/tools/CronScheduler/components/DayChips.tsx +13 -11
- package/src/tools/CronScheduler/components/MonthDayGrid.tsx +4 -4
- package/src/tools/CronScheduler/components/SchedulePreview.tsx +7 -3
- package/src/tools/CronScheduler/components/TimeSelector.tsx +1 -1
- package/src/tools/CronScheduler/index.tsx +1 -1
- package/src/tools/CronScheduler/types/index.ts +8 -3
- package/src/tools/CronScheduler/utils/cron-humanize.ts +61 -16
- package/src/tools/CronScheduler/utils/cron-parser.ts +13 -4
- package/src/tools/FileIcon/FileIcon.tsx +24 -39
- package/src/tools/FileIcon/get-file-icon.ts +73 -0
- package/src/tools/FileIcon/icons/icon-data.ts +399 -0
- package/src/tools/FileIcon/index.ts +4 -0
- package/src/tools/FileIcon/loader.ts +17 -35
- package/src/tools/FileIcon/specialFolders.ts +18 -0
- package/src/tools/Gallery/components/lightbox/GalleryLightbox.tsx +112 -35
- package/src/tools/Gallery/components/media/GalleryVideo.tsx +21 -2
- package/src/tools/Gallery/components/preview/GalleryCarousel.tsx +11 -1
- package/src/tools/Gallery/hooks/usePreloadImages.ts +54 -7
- package/src/tools/ImageViewer/components/ImageInfo.tsx +12 -1
- package/src/tools/ImageViewer/components/ImageToolbar.tsx +51 -43
- package/src/tools/ImageViewer/components/ImageViewer.tsx +106 -26
- package/src/tools/ImageViewer/hooks/useImageLoading.ts +13 -0
- package/src/tools/ImageViewer/utils/constants.ts +3 -0
- package/src/tools/ImageViewer/utils/index.ts +1 -0
- package/src/tools/JsonForm/JsonSchemaForm.tsx +4 -1
- package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +5 -3
- package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +7 -4
- package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +3 -1
- package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +23 -3
- package/src/tools/JsonForm/widgets/ColorWidget.tsx +20 -12
- package/src/tools/JsonForm/widgets/NumberWidget.tsx +14 -9
- package/src/tools/JsonForm/widgets/RadioWidget.tsx +78 -0
- package/src/tools/JsonForm/widgets/SelectWidget.tsx +1 -0
- package/src/tools/JsonForm/widgets/SliderWidget.tsx +7 -4
- package/src/tools/JsonForm/widgets/TextWidget.tsx +41 -17
- package/src/tools/JsonForm/widgets/index.ts +1 -0
- package/src/tools/JsonTree/components/JsonContent.tsx +115 -40
- package/src/tools/LottiePlayer/LottiePlayer.client.tsx +177 -72
- package/src/tools/LottiePlayer/index.tsx +14 -4
- package/src/tools/LottiePlayer/lazy.tsx +11 -3
- package/src/tools/LottiePlayer/types.ts +31 -1
- package/src/tools/LottiePlayer/useLottie.ts +32 -9
- package/src/tools/LottiePlayer/usePrefersReducedMotion.ts +46 -0
- package/src/tools/Map/components/LayerSwitcher.tsx +54 -21
- package/src/tools/Map/components/MapCluster.tsx +28 -21
- package/src/tools/Map/components/MapContainer.tsx +11 -4
- package/src/tools/Map/components/MapLegend.tsx +46 -15
- package/src/tools/Map/components/MapMarker.tsx +31 -2
- package/src/tools/Map/hooks/useMapEvents.ts +64 -105
- package/src/tools/MarkdownEditor/MarkdownEditor.tsx +61 -6
- package/src/tools/MarkdownEditor/MentionList.tsx +37 -4
- package/src/tools/MarkdownEditor/createMentionSuggestion.ts +11 -0
- package/src/tools/MarkdownEditor/lazy.tsx +32 -7
- package/src/tools/MarkdownEditor/styles.css +13 -0
- package/src/tools/MarkdownMessage/CodeBlock.tsx +40 -17
- package/src/tools/MarkdownMessage/MarkdownMessage.tsx +26 -6
- package/src/tools/MarkdownMessage/components.tsx +22 -9
- package/src/tools/MarkdownMessage/types.ts +24 -1
- package/src/tools/Mermaid/Mermaid.client.tsx +27 -5
- package/src/tools/Mermaid/components/MermaidErrorPanel.tsx +31 -0
- package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +14 -17
- package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +264 -168
- package/src/tools/Mermaid/hooks/useMermaidValidation.ts +76 -10
- package/src/tools/Mermaid/index.tsx +6 -0
- package/src/tools/Mermaid/utils/mermaid-helpers.ts +141 -18
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/FieldRow.tsx +11 -1
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts +49 -20
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/index.tsx +7 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/grouping.ts +7 -4
- package/src/tools/OpenapiViewer/constants.ts +3 -0
- package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +73 -11
- package/src/tools/OpenapiViewer/utils/schemaExport.ts +26 -6
- package/src/tools/PrettyCode/PrettyCode.client.tsx +23 -16
- package/src/tools/PrettyCode/lazy.tsx +1 -1
- package/src/tools/SpeechRecognition/README.md +1 -1
- package/src/tools/SpeechRecognition/__tests__/language.test.ts +9 -3
- package/src/tools/SpeechRecognition/components/RecordingPulse.tsx +59 -0
- package/src/tools/SpeechRecognition/components/index.ts +2 -0
- package/src/tools/SpeechRecognition/core/engine/external.ts +24 -7
- package/src/tools/SpeechRecognition/core/language.ts +23 -6
- package/src/tools/SpeechRecognition/hooks/usePushToTalk.ts +36 -5
- package/src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts +18 -11
- package/src/tools/SpeechRecognition/widgets/VoiceComposerSlot.tsx +94 -26
- package/src/tools/SpeechRecognition/widgets/index.ts +1 -1
- package/src/tools/Tree/README.md +4 -8
- package/src/tools/Tree/TreeRoot.tsx +22 -10
- package/src/tools/Tree/components/TreeContent.tsx +24 -4
- package/src/tools/Tree/components/TreeLabel.tsx +8 -2
- package/src/tools/Tree/components/TreeRow.tsx +16 -6
- package/src/tools/Tree/data/flatten.ts +10 -4
- package/src/tools/Tree/types.ts +4 -0
- package/src/tools/Uploader/components/UploadAddButton.tsx +29 -6
- package/src/tools/Uploader/components/UploadDropzone.tsx +63 -7
- package/src/tools/Uploader/components/UploadPageDropOverlay.tsx +19 -5
- package/src/tools/Uploader/components/UploadPreviewItem.tsx +47 -17
- package/src/tools/Uploader/components/UploadPreviewList.tsx +24 -12
- package/src/tools/Uploader/utils/formatters.ts +8 -3
- package/src/tools/VideoPlayer/README.md +87 -230
- package/src/tools/VideoPlayer/VideoPlayer.tsx +82 -0
- package/src/tools/VideoPlayer/canvas/canvas-dispatcher.tsx +34 -0
- package/src/tools/VideoPlayer/canvas/hls-canvas.tsx +39 -0
- package/src/tools/VideoPlayer/canvas/iframe-canvas.tsx +33 -0
- package/src/tools/VideoPlayer/canvas/index.ts +12 -0
- package/src/tools/VideoPlayer/canvas/jsx-augmentation.ts +47 -0
- package/src/tools/VideoPlayer/canvas/native-canvas.tsx +38 -0
- package/src/tools/VideoPlayer/canvas/vimeo-canvas.tsx +40 -0
- package/src/tools/VideoPlayer/canvas/youtube-canvas.tsx +78 -0
- package/src/tools/VideoPlayer/index.ts +51 -65
- package/src/tools/VideoPlayer/lazy.tsx +11 -54
- package/src/tools/VideoPlayer/parts/controls-bar.tsx +35 -0
- package/src/tools/VideoPlayer/parts/fullscreen.tsx +19 -0
- package/src/tools/VideoPlayer/parts/index.ts +15 -0
- package/src/tools/VideoPlayer/parts/pip.tsx +19 -0
- package/src/tools/VideoPlayer/parts/play-button.tsx +19 -0
- package/src/tools/VideoPlayer/parts/playback-rate.tsx +31 -0
- package/src/tools/VideoPlayer/parts/poster.tsx +3 -0
- package/src/tools/VideoPlayer/parts/seek-bar.tsx +26 -0
- package/src/tools/VideoPlayer/parts/volume.tsx +32 -0
- package/src/tools/VideoPlayer/styles/video-player.css +141 -0
- package/src/tools/VideoPlayer/types.ts +82 -0
- package/src/tools/VideoPlayer/utils/parse-embed-url.ts +70 -0
- package/src/tools/VideoPlayer/utils/vimeo-id.ts +24 -0
- package/src/tools/VideoPlayer/utils/youtube-id.ts +64 -0
- package/src/tools/index.ts +37 -29
- package/src/tools/Chat/components/AudioToggle.tsx +0 -78
- package/src/tools/Chat/components/ChatRoot.tsx +0 -305
- package/src/tools/Chat/components/Composer.tsx +0 -216
- package/src/tools/Chat/hooks/useChatScroll.ts +0 -145
- package/src/tools/Chat/types.ts +0 -9
- package/src/tools/JsonTree/components/JsonToolbar.tsx +0 -95
- package/src/tools/JsonTree/hooks/useElementCorner.ts +0 -84
- package/src/tools/JsonTree/hooks/useNavbarHeight.ts +0 -83
- package/src/tools/OpenapiViewer/components/DocsLayout/schemaFields.ts +0 -121
- package/src/tools/Tour/README.md +0 -373
- package/src/tools/Tour/components/Tour.tsx +0 -12
- package/src/tools/Tour/components/TourContent.tsx +0 -171
- package/src/tools/Tour/components/TourNavigation.tsx +0 -77
- package/src/tools/Tour/components/TourProgress.tsx +0 -88
- package/src/tools/Tour/components/TourSpotlight.tsx +0 -199
- package/src/tools/Tour/components/index.ts +0 -5
- package/src/tools/Tour/context/TourContext.ts +0 -19
- package/src/tools/Tour/context/TourProvider.tsx +0 -292
- package/src/tools/Tour/context/index.ts +0 -2
- package/src/tools/Tour/hooks/index.ts +0 -3
- package/src/tools/Tour/hooks/useKeyboardNavigation.ts +0 -59
- package/src/tools/Tour/hooks/useStepTarget.ts +0 -121
- package/src/tools/Tour/hooks/useTour.ts +0 -42
- package/src/tools/Tour/index.ts +0 -38
- package/src/tools/Tour/types/index.ts +0 -224
- package/src/tools/Tour/utils/dom.ts +0 -98
- package/src/tools/Tour/utils/index.ts +0 -3
- package/src/tools/Tour/utils/logger.ts +0 -3
- package/src/tools/Tour/utils/scrollIntoView.ts +0 -24
- package/src/tools/VideoPlayer/components/VideoControls.tsx +0 -138
- package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +0 -172
- package/src/tools/VideoPlayer/components/VideoPlayer.tsx +0 -201
- package/src/tools/VideoPlayer/components/index.ts +0 -14
- package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +0 -52
- package/src/tools/VideoPlayer/context/index.ts +0 -8
- package/src/tools/VideoPlayer/hooks/index.ts +0 -12
- package/src/tools/VideoPlayer/hooks/useVideoPlayerSettings.ts +0 -71
- package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +0 -117
- package/src/tools/VideoPlayer/providers/NativeProvider.tsx +0 -284
- package/src/tools/VideoPlayer/providers/StreamProvider.tsx +0 -505
- package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +0 -397
- package/src/tools/VideoPlayer/providers/index.ts +0 -8
- package/src/tools/VideoPlayer/types/index.ts +0 -38
- package/src/tools/VideoPlayer/types/player.ts +0 -116
- package/src/tools/VideoPlayer/types/provider.ts +0 -93
- package/src/tools/VideoPlayer/types/sources.ts +0 -97
- package/src/tools/VideoPlayer/utils/debug.ts +0 -14
- package/src/tools/VideoPlayer/utils/fileSource.ts +0 -78
- package/src/tools/VideoPlayer/utils/index.ts +0 -12
- package/src/tools/VideoPlayer/utils/resolvers.ts +0 -75
- /package/src/tools/Chat/{config.ts → constants.ts} +0 -0
- /package/src/tools/Chat/launcher/{ChatHeaderAudioToggle.tsx → header/ChatHeaderAudioToggle.tsx} +0 -0
- /package/src/tools/Chat/{components → messages}/Attachments.tsx +0 -0
- /package/src/tools/Chat/{components → messages}/JumpToLatest.tsx +0 -0
- /package/src/tools/Chat/{components → messages}/MessageActions.tsx +0 -0
- /package/src/tools/Chat/{components → messages}/Sources.tsx +0 -0
- /package/src/tools/Chat/{components → messages}/StreamingIndicator.tsx +0 -0
- /package/src/tools/Chat/{components → messages}/ToolCalls.tsx +0 -0
- /package/src/tools/Chat/{components → shell}/ErrorBanner.tsx +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* media-chrome theme.
|
|
3
|
+
*
|
|
4
|
+
* The video canvas is ALWAYS a black surface, so the control chrome is
|
|
5
|
+
* themed against on-black contrast — icons/text stay light in both the
|
|
6
|
+
* light and dark app themes. Only the accent (progress bar / thumb) and
|
|
7
|
+
* the scrub-time popover follow semantic tokens, since the popover is a
|
|
8
|
+
* detached surface that should match the rest of the platform.
|
|
9
|
+
*
|
|
10
|
+
* media-chrome ships its own focus-ring + tooltip styles; we only override
|
|
11
|
+
* what's needed to match the rest of the platform.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
media-controller {
|
|
15
|
+
/* On-black control chrome — fixed regardless of app theme. */
|
|
16
|
+
--video-on-canvas: rgb(245 245 245);
|
|
17
|
+
|
|
18
|
+
/* Surfaces */
|
|
19
|
+
--media-control-background: transparent;
|
|
20
|
+
--media-control-hover-background: rgb(255 255 255 / 0.14);
|
|
21
|
+
--media-control-padding: 0;
|
|
22
|
+
|
|
23
|
+
/* Foreground / accent */
|
|
24
|
+
--media-primary-color: var(--primary);
|
|
25
|
+
--media-secondary-color: rgb(255 255 255 / 0.6);
|
|
26
|
+
--media-text-color: var(--video-on-canvas);
|
|
27
|
+
--media-icon-color: var(--video-on-canvas);
|
|
28
|
+
--media-loading-icon-color: var(--video-on-canvas);
|
|
29
|
+
|
|
30
|
+
/* Range / progress bar — thin translucent rail, small accent thumb.
|
|
31
|
+
The range element keeps a tall hit-area; only the painted track is
|
|
32
|
+
4px so it reads as a slim progress line over the video. */
|
|
33
|
+
--media-range-track-background: color-mix(in oklab, white 28%, transparent);
|
|
34
|
+
--media-range-track-border-radius: 9999px;
|
|
35
|
+
--media-range-track-height: 4px;
|
|
36
|
+
--media-range-track-pointer-background: color-mix(in oklab, white 40%, transparent);
|
|
37
|
+
--media-range-bar-color: var(--primary);
|
|
38
|
+
--media-range-thumb-background: var(--primary);
|
|
39
|
+
--media-range-thumb-border-radius: 9999px;
|
|
40
|
+
--media-range-thumb-width: 12px;
|
|
41
|
+
--media-range-thumb-height: 12px;
|
|
42
|
+
--media-range-thumb-opacity: 0;
|
|
43
|
+
--media-range-thumb-transition: opacity 0.15s ease;
|
|
44
|
+
|
|
45
|
+
/* Tooltip */
|
|
46
|
+
--media-tooltip-background: var(--popover);
|
|
47
|
+
--media-tooltip-color: var(--popover-foreground);
|
|
48
|
+
--media-tooltip-border-radius: 6px;
|
|
49
|
+
|
|
50
|
+
/* Font */
|
|
51
|
+
--media-font-family: inherit;
|
|
52
|
+
--media-font-size: 12px;
|
|
53
|
+
|
|
54
|
+
/* Layout */
|
|
55
|
+
display: block;
|
|
56
|
+
position: relative;
|
|
57
|
+
width: 100%;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Square icon buttons should size to the wrapper. */
|
|
61
|
+
media-controller .media-control-square::part(button) {
|
|
62
|
+
width: 100%;
|
|
63
|
+
height: 100%;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* Control buttons / text — fixed on-black colours. The video canvas is
|
|
68
|
+
* always dark, so these never follow the app's light/dark theme.
|
|
69
|
+
*/
|
|
70
|
+
.video-player__control {
|
|
71
|
+
color: var(--video-on-canvas, rgb(245 245 245));
|
|
72
|
+
border-radius: 0.375rem;
|
|
73
|
+
transition: background-color 0.15s ease;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.video-player__control:hover {
|
|
77
|
+
background-color: rgb(255 255 255 / 0.14);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.video-player__time {
|
|
81
|
+
color: rgb(255 255 255 / 0.72);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Hide the default control bar background — we paint our own gradient
|
|
85
|
+
scrim via the <ControlsBar> wrapper. */
|
|
86
|
+
media-control-bar {
|
|
87
|
+
background: transparent;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
* Auto-hide. media-chrome flags inactivity by setting `userinactive` on
|
|
92
|
+
* the <media-controller>; it only does so while playback is running, and
|
|
93
|
+
* removes it on mousemove / pause / focus. We fade the whole control bar
|
|
94
|
+
* (controls + gradient scrim) together with a smooth opacity transition.
|
|
95
|
+
*/
|
|
96
|
+
.video-player__control-bar {
|
|
97
|
+
opacity: 1;
|
|
98
|
+
transition: opacity 0.3s ease-out;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
media-controller[userinactive]:not([mediapaused]) .video-player__control-bar {
|
|
102
|
+
opacity: 0;
|
|
103
|
+
pointer-events: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/*
|
|
107
|
+
* Seek-bar hover preview. `<media-time-range>` exposes two slotted
|
|
108
|
+
* boxes: `preview-box` (a 120×109 thumbnail panel) and `current-box`
|
|
109
|
+
* (the scrub time label). With no `thumbnails` track wired up the
|
|
110
|
+
* preview-box has zero slotted content but still paints its default
|
|
111
|
+
* dark `rgb(31,31,31)` background — it shows as a stray empty
|
|
112
|
+
* rectangle floating over the video.
|
|
113
|
+
*
|
|
114
|
+
* Hide the empty preview-box entirely; keep `current-box` and style
|
|
115
|
+
* its time label as a compact popover chip.
|
|
116
|
+
*/
|
|
117
|
+
media-time-range {
|
|
118
|
+
/* media-chrome's own preview/box vars — point them at our popover
|
|
119
|
+
surface so the scrub time chip matches the rest of the controls. */
|
|
120
|
+
--media-preview-background: var(--popover);
|
|
121
|
+
--media-preview-border-radius: 6px;
|
|
122
|
+
--media-text-color: var(--popover-foreground);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* Reveal the accent thumb only while hovering / scrubbing the rail. */
|
|
126
|
+
media-time-range:hover {
|
|
127
|
+
--media-range-thumb-opacity: 1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
media-time-range::part(preview-box) {
|
|
131
|
+
display: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
media-time-range::part(current-box) {
|
|
135
|
+
padding: 2px 6px;
|
|
136
|
+
border-radius: 6px;
|
|
137
|
+
background: var(--popover) !important;
|
|
138
|
+
color: var(--popover-foreground);
|
|
139
|
+
font-size: 11px;
|
|
140
|
+
box-shadow: 0 4px 12px color-mix(in oklab, var(--foreground) 18%, transparent);
|
|
141
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VideoPlayer types — discriminated `VideoSource` union + props.
|
|
3
|
+
*
|
|
4
|
+
* The component is engine-agnostic at the API surface: callers either
|
|
5
|
+
* pass a structured `VideoSource` or a raw URL string (auto-parsed via
|
|
6
|
+
* `parseEmbedUrl`).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ReactNode } from 'react';
|
|
10
|
+
|
|
11
|
+
export interface UrlSource {
|
|
12
|
+
readonly type: 'url';
|
|
13
|
+
readonly url: string;
|
|
14
|
+
readonly mimeType?: string;
|
|
15
|
+
readonly title?: string;
|
|
16
|
+
readonly poster?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface YouTubeSource {
|
|
20
|
+
readonly type: 'youtube';
|
|
21
|
+
readonly videoId: string;
|
|
22
|
+
readonly startTime?: number;
|
|
23
|
+
readonly playlistId?: string;
|
|
24
|
+
readonly title?: string;
|
|
25
|
+
readonly poster?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface VimeoSource {
|
|
29
|
+
readonly type: 'vimeo';
|
|
30
|
+
readonly videoId: string;
|
|
31
|
+
readonly startTime?: number;
|
|
32
|
+
readonly title?: string;
|
|
33
|
+
readonly poster?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface HlsSource {
|
|
37
|
+
readonly type: 'hls';
|
|
38
|
+
readonly url: string;
|
|
39
|
+
readonly title?: string;
|
|
40
|
+
readonly poster?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface IframeSource {
|
|
44
|
+
readonly type: 'iframe';
|
|
45
|
+
readonly url: string;
|
|
46
|
+
readonly title?: string;
|
|
47
|
+
readonly poster?: string;
|
|
48
|
+
readonly allow?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type VideoSource =
|
|
52
|
+
| UrlSource
|
|
53
|
+
| YouTubeSource
|
|
54
|
+
| VimeoSource
|
|
55
|
+
| HlsSource
|
|
56
|
+
| IframeSource;
|
|
57
|
+
|
|
58
|
+
export type AspectRatioValue = number | 'auto' | 'fill';
|
|
59
|
+
|
|
60
|
+
export interface VideoPlayerSettings {
|
|
61
|
+
readonly autoPlay?: boolean;
|
|
62
|
+
readonly muted?: boolean;
|
|
63
|
+
readonly loop?: boolean;
|
|
64
|
+
readonly playsInline?: boolean;
|
|
65
|
+
readonly crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
|
66
|
+
readonly preload?: 'none' | 'metadata' | 'auto';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface VideoPlayerProps extends VideoPlayerSettings {
|
|
70
|
+
/**
|
|
71
|
+
* Structured source object — or a raw URL string that will be
|
|
72
|
+
* auto-classified via `parseEmbedUrl` (YouTube / Vimeo / HLS / MP4 / iframe).
|
|
73
|
+
*/
|
|
74
|
+
readonly source: VideoSource | string;
|
|
75
|
+
/** Default `true`. When `false`, no built-in `<MediaControlBar>` is rendered. */
|
|
76
|
+
readonly controls?: boolean;
|
|
77
|
+
/** Default `16/9`. `'fill'` stretches to parent height; `'auto'` keeps intrinsic. */
|
|
78
|
+
readonly aspectRatio?: AspectRatioValue;
|
|
79
|
+
readonly className?: string;
|
|
80
|
+
/** Custom children replace the default control bar entirely. */
|
|
81
|
+
readonly children?: ReactNode;
|
|
82
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart URL classifier — maps an arbitrary string into a structured
|
|
3
|
+
* `VideoSource`.
|
|
4
|
+
*
|
|
5
|
+
* Order:
|
|
6
|
+
* 1. YouTube (youtube.com, youtu.be, shorts, embed)
|
|
7
|
+
* 2. Vimeo (vimeo.com, player.vimeo.com)
|
|
8
|
+
* 3. HLS (`.m3u8`)
|
|
9
|
+
* 4. Native (`.mp4`, `.webm`, `.mov`, `.mkv`, `.ogv`, `.m4v`)
|
|
10
|
+
* 5. Fallback — treat as iframe embed.
|
|
11
|
+
*
|
|
12
|
+
* Pure; no React, no DOM.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { VideoSource } from '../types';
|
|
16
|
+
import { extractYouTubeId, parseYouTubeStartTime } from './youtube-id';
|
|
17
|
+
import { extractVimeoId } from './vimeo-id';
|
|
18
|
+
|
|
19
|
+
const NATIVE_VIDEO_EXT = /\.(mp4|webm|mov|mkv|ogv|m4v)(\?.*)?$/i;
|
|
20
|
+
const HLS_EXT = /\.m3u8(\?.*)?$/i;
|
|
21
|
+
|
|
22
|
+
export function parseEmbedUrl(input: string): VideoSource {
|
|
23
|
+
const trimmed = input.trim();
|
|
24
|
+
|
|
25
|
+
// 1. YouTube.
|
|
26
|
+
const ytId = extractYouTubeId(trimmed);
|
|
27
|
+
if (ytId) {
|
|
28
|
+
let startTime: number | undefined;
|
|
29
|
+
let playlistId: string | undefined;
|
|
30
|
+
try {
|
|
31
|
+
const url = new URL(trimmed);
|
|
32
|
+
startTime = parseYouTubeStartTime(url.searchParams.get('t'));
|
|
33
|
+
const list = url.searchParams.get('list');
|
|
34
|
+
if (list && /^[\w-]+$/.test(list)) playlistId = list;
|
|
35
|
+
} catch {
|
|
36
|
+
/* ignore */
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
type: 'youtube',
|
|
40
|
+
videoId: ytId,
|
|
41
|
+
...(startTime !== undefined && { startTime }),
|
|
42
|
+
...(playlistId && { playlistId }),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 2. Vimeo.
|
|
47
|
+
const vimeoId = extractVimeoId(trimmed);
|
|
48
|
+
if (vimeoId) {
|
|
49
|
+
return { type: 'vimeo', videoId: vimeoId };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 3. HLS.
|
|
53
|
+
if (HLS_EXT.test(trimmed)) {
|
|
54
|
+
return { type: 'hls', url: trimmed };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 4. Native video file.
|
|
58
|
+
if (NATIVE_VIDEO_EXT.test(trimmed)) {
|
|
59
|
+
return { type: 'url', url: trimmed };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 5. Fallback: blob: / data: / unknown http(s) URL — assume native <video>
|
|
63
|
+
// can handle blob/data, iframe for everything else.
|
|
64
|
+
if (/^(blob:|data:)/i.test(trimmed)) {
|
|
65
|
+
return { type: 'url', url: trimmed };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Unknown URL — fall back to iframe so embeds still surface.
|
|
69
|
+
return { type: 'iframe', url: trimmed };
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a Vimeo numeric `videoId` from a URL.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - vimeo.com/123456789
|
|
6
|
+
* - vimeo.com/123456789/HASH
|
|
7
|
+
* - player.vimeo.com/video/123456789
|
|
8
|
+
*
|
|
9
|
+
* Returns `null` if the URL does not match.
|
|
10
|
+
*/
|
|
11
|
+
export function extractVimeoId(input: string): string | null {
|
|
12
|
+
let url: URL;
|
|
13
|
+
try {
|
|
14
|
+
url = new URL(input);
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const host = url.hostname.replace(/^www\./, '');
|
|
19
|
+
if (host !== 'vimeo.com' && host !== 'player.vimeo.com') return null;
|
|
20
|
+
|
|
21
|
+
// /video/<id> on player.vimeo.com, /<id> on vimeo.com.
|
|
22
|
+
const match = url.pathname.match(/(?:^\/video\/|^\/)(\d+)/);
|
|
23
|
+
return match ? match[1] : null;
|
|
24
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a YouTube `videoId` from a URL.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - youtube.com/watch?v=ID
|
|
6
|
+
* - youtu.be/ID
|
|
7
|
+
* - youtube.com/shorts/ID
|
|
8
|
+
* - youtube.com/embed/ID
|
|
9
|
+
* - youtube.com/v/ID
|
|
10
|
+
* - m.youtube.com/* mirrors
|
|
11
|
+
*
|
|
12
|
+
* Returns `null` if the URL does not match.
|
|
13
|
+
*/
|
|
14
|
+
export function extractYouTubeId(input: string): string | null {
|
|
15
|
+
let url: URL;
|
|
16
|
+
try {
|
|
17
|
+
url = new URL(input);
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const host = url.hostname.replace(/^www\.|^m\./, '');
|
|
23
|
+
|
|
24
|
+
if (host === 'youtu.be') {
|
|
25
|
+
const id = url.pathname.replace(/^\//, '').split('/')[0];
|
|
26
|
+
return isValidId(id) ? id : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (host === 'youtube.com' || host === 'youtube-nocookie.com') {
|
|
30
|
+
if (url.pathname === '/watch') {
|
|
31
|
+
const v = url.searchParams.get('v');
|
|
32
|
+
return v && isValidId(v) ? v : null;
|
|
33
|
+
}
|
|
34
|
+
const m = url.pathname.match(/^\/(?:shorts|embed|v|live)\/([^/?#]+)/);
|
|
35
|
+
if (m) {
|
|
36
|
+
return isValidId(m[1]) ? m[1] : null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Parse the YouTube `?t=` / `&t=` start-time param (`90`, `90s`, `1m30s`). */
|
|
44
|
+
export function parseYouTubeStartTime(input: string | null): number | undefined {
|
|
45
|
+
if (!input) return undefined;
|
|
46
|
+
// Pure seconds.
|
|
47
|
+
if (/^\d+s?$/.test(input)) {
|
|
48
|
+
const n = parseInt(input, 10);
|
|
49
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
50
|
+
}
|
|
51
|
+
// `1h2m3s` / `2m30s` / `45s`.
|
|
52
|
+
const match = input.match(/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s?)?$/);
|
|
53
|
+
if (!match) return undefined;
|
|
54
|
+
const [, h, m, s] = match;
|
|
55
|
+
const total =
|
|
56
|
+
(h ? parseInt(h, 10) * 3600 : 0) +
|
|
57
|
+
(m ? parseInt(m, 10) * 60 : 0) +
|
|
58
|
+
(s ? parseInt(s, 10) : 0);
|
|
59
|
+
return total > 0 ? total : undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isValidId(id: string | undefined): id is string {
|
|
63
|
+
return !!id && /^[\w-]{6,}$/.test(id);
|
|
64
|
+
}
|
package/src/tools/index.ts
CHANGED
|
@@ -22,12 +22,13 @@ export type { JsonTreeConfig } from './JsonTree';
|
|
|
22
22
|
export { default as Mermaid } from './Mermaid';
|
|
23
23
|
export { default as PrettyCode } from './PrettyCode';
|
|
24
24
|
export type { Language } from './PrettyCode';
|
|
25
|
-
export { LottiePlayer, useLottie } from './LottiePlayer';
|
|
25
|
+
export { LottiePlayer, useLottie, usePrefersReducedMotion } from './LottiePlayer';
|
|
26
26
|
export type {
|
|
27
27
|
LottiePlayerProps,
|
|
28
28
|
LottieSize,
|
|
29
29
|
LottieSpeed,
|
|
30
30
|
LottieDirection,
|
|
31
|
+
LottieSegment,
|
|
31
32
|
UseLottieOptions,
|
|
32
33
|
UseLottieReturn,
|
|
33
34
|
} from './LottiePlayer';
|
|
@@ -43,43 +44,50 @@ export * from './JsonForm/utils';
|
|
|
43
44
|
export { default as OpenapiViewer } from './OpenapiViewer';
|
|
44
45
|
export type { PlaygroundConfig, SchemaSource, PlaygroundProps } from './OpenapiViewer';
|
|
45
46
|
|
|
46
|
-
// Export VideoPlayer
|
|
47
|
+
// Export VideoPlayer (media-chrome shell with provider-aware canvases)
|
|
47
48
|
export {
|
|
48
49
|
VideoPlayer,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
CanvasDispatcher,
|
|
51
|
+
NativeCanvas,
|
|
52
|
+
YouTubeCanvas,
|
|
53
|
+
VimeoCanvas,
|
|
54
|
+
HlsCanvas,
|
|
55
|
+
IframeCanvas,
|
|
56
|
+
PlayButton,
|
|
57
|
+
SeekBar,
|
|
58
|
+
Volume,
|
|
59
|
+
Fullscreen,
|
|
60
|
+
Pip,
|
|
61
|
+
PlaybackRate,
|
|
62
|
+
ControlsBar,
|
|
63
|
+
Poster,
|
|
64
|
+
parseEmbedUrl,
|
|
65
|
+
extractYouTubeId,
|
|
66
|
+
extractVimeoId,
|
|
61
67
|
} from './VideoPlayer';
|
|
62
68
|
export type {
|
|
63
|
-
|
|
69
|
+
VideoSource,
|
|
64
70
|
UrlSource,
|
|
65
71
|
YouTubeSource,
|
|
66
72
|
VimeoSource,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
StreamSource,
|
|
70
|
-
BlobSource,
|
|
71
|
-
DataUrlSource,
|
|
72
|
-
PlayerMode,
|
|
73
|
+
HlsSource,
|
|
74
|
+
IframeSource,
|
|
73
75
|
AspectRatioValue,
|
|
74
76
|
VideoPlayerProps,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
VideoPlayerSettings,
|
|
78
|
+
PlayButtonProps,
|
|
79
|
+
SeekBarProps,
|
|
80
|
+
VolumeProps,
|
|
81
|
+
FullscreenProps,
|
|
82
|
+
PipProps,
|
|
83
|
+
PlaybackRateProps,
|
|
84
|
+
ControlsBarProps,
|
|
85
|
+
CanvasDispatcherProps,
|
|
86
|
+
NativeCanvasProps,
|
|
87
|
+
YouTubeCanvasProps,
|
|
88
|
+
VimeoCanvasProps,
|
|
89
|
+
HlsCanvasProps,
|
|
90
|
+
IframeCanvasProps,
|
|
83
91
|
} from './VideoPlayer';
|
|
84
92
|
|
|
85
93
|
// AudioPlayer v6 — under construction (see @dev/@refactoring6-audioplayer/).
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Mute / unmute toggle for chat audio events.
|
|
5
|
-
*
|
|
6
|
-
* Reads the current ``muted`` state from the active chat context and
|
|
7
|
-
* persists changes through ``useChatAudioPrefs`` (cross-tab safe). The
|
|
8
|
-
* button auto-hides when no ``audio.sounds`` config is provided —
|
|
9
|
-
* showing a mute toggle for a chat with no sounds is just clutter.
|
|
10
|
-
*
|
|
11
|
-
* Drop into a ChatRoot ``header`` slot or anywhere inside a chat
|
|
12
|
-
* provider:
|
|
13
|
-
*
|
|
14
|
-
* ```tsx
|
|
15
|
-
* <ChatRoot
|
|
16
|
-
* header={<AudioToggle />}
|
|
17
|
-
* audio={{ sounds: { messageReceived: '/ping.mp3' } }}
|
|
18
|
-
* ...
|
|
19
|
-
* />
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { Volume2, VolumeX } from 'lucide-react';
|
|
24
|
-
|
|
25
|
-
import { Button } from '@djangocfg/ui-core/components';
|
|
26
|
-
import { cn } from '@djangocfg/ui-core/lib';
|
|
27
|
-
|
|
28
|
-
import { useChatContextOptional } from '../context';
|
|
29
|
-
import { useChatAudioPrefs } from '../core/audio/preferences';
|
|
30
|
-
|
|
31
|
-
export interface AudioToggleProps {
|
|
32
|
-
/** Visual size — matches Button sizes. Default: ``icon``. */
|
|
33
|
-
size?: 'sm' | 'icon';
|
|
34
|
-
/** Variant passed to the underlying Button. Default: ``ghost``. */
|
|
35
|
-
variant?: 'ghost' | 'outline' | 'secondary';
|
|
36
|
-
/** Force-show even when no audio config is wired (e.g. for stories). */
|
|
37
|
-
alwaysShow?: boolean;
|
|
38
|
-
className?: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function AudioToggle({
|
|
42
|
-
size = 'icon',
|
|
43
|
-
variant = 'ghost',
|
|
44
|
-
alwaysShow = false,
|
|
45
|
-
className,
|
|
46
|
-
}: AudioToggleProps) {
|
|
47
|
-
// Read straight from the persist store so the toggle works even
|
|
48
|
-
// when rendered OUTSIDE the ChatRoot (e.g. in a parent header). The
|
|
49
|
-
// chat audio bus reads the same store, so a click here flips the
|
|
50
|
-
// "muted" state for any sibling ChatRoot in the same tab and
|
|
51
|
-
// mirrors across tabs via the storage event.
|
|
52
|
-
const muted = useChatAudioPrefs((s) => s.muted);
|
|
53
|
-
const setMuted = useChatAudioPrefs((s) => s.setMuted);
|
|
54
|
-
|
|
55
|
-
// If a ChatRoot is in scope, hide unless it actually wired sounds —
|
|
56
|
-
// otherwise the button is a no-op for that surface. When rendered
|
|
57
|
-
// standalone (no context), default to visible.
|
|
58
|
-
const ctx = useChatContextOptional();
|
|
59
|
-
if (ctx && !ctx.hasAudio && !alwaysShow) return null;
|
|
60
|
-
|
|
61
|
-
const Icon = muted ? VolumeX : Volume2;
|
|
62
|
-
const label = muted ? 'Unmute chat sounds' : 'Mute chat sounds';
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<Button
|
|
66
|
-
type="button"
|
|
67
|
-
variant={variant}
|
|
68
|
-
size={size}
|
|
69
|
-
onClick={() => setMuted(!muted)}
|
|
70
|
-
aria-label={label}
|
|
71
|
-
aria-pressed={muted}
|
|
72
|
-
title={label}
|
|
73
|
-
className={cn(size === 'icon' ? 'h-9 w-9' : '', className)}
|
|
74
|
-
>
|
|
75
|
-
<Icon aria-hidden className="size-4" />
|
|
76
|
-
</Button>
|
|
77
|
-
);
|
|
78
|
-
}
|