@therealtinhtute/baroiplayer 1.2.1 → 2.0.0-beta.1
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 +90 -71
- package/dist/components/icons/index.d.ts +36 -0
- package/dist/components/icons/index.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/AudioIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/AudioIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/BackwardIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/BackwardIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/CameraIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/CameraIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/CheckIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/CheckIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ForwardIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/ForwardIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/LoadingIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/LoadingIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PauseIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PauseIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PlayIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PlayIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/QualityIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/QualityIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SettingsIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SettingsIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SliderIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SliderIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SubtitleIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SubtitleIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/UnPiPIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/UnPiPIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-audio.d.ts +13 -0
- package/dist/components/variants/gradient/gradient-audio.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-controls.d.ts +4 -0
- package/dist/components/variants/gradient/gradient-controls.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-glyphs.d.ts +30 -0
- package/dist/components/variants/gradient/gradient-glyphs.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-video.d.ts +16 -0
- package/dist/components/variants/gradient/gradient-video.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +750 -5640
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +3 -0
- package/package.json +110 -114
- package/src/components/variants/gradient/gradient-audio.tsx +47 -0
- package/src/components/variants/gradient/gradient-controls.tsx +254 -0
- package/src/components/variants/gradient/gradient-glyphs.test.tsx +69 -0
- package/src/components/variants/gradient/gradient-glyphs.tsx +129 -0
- package/src/components/variants/gradient/gradient-skin.css +211 -0
- package/src/components/variants/gradient/gradient-video.tsx +70 -0
- package/src/index.ts +5 -198
- package/src/test/accessibility-utils.ts +0 -59
- package/dist/context/media.js +0 -1
- package/dist/context/media.mjs +0 -3
- package/dist/context/store.js +0 -1
- package/dist/context/store.mjs +0 -3
- package/dist/context-Bzd5QCKM.cjs +0 -7
- package/dist/context-Bzd5QCKM.cjs.map +0 -1
- package/dist/context-DD_SH4tT.js +0 -1053
- package/dist/context-DD_SH4tT.js.map +0 -1
- package/dist/core-events-BRnLMB7s.cjs +0 -2
- package/dist/core-events-BRnLMB7s.cjs.map +0 -1
- package/dist/core-events-v_mKdj5p.js +0 -417
- package/dist/core-events-v_mKdj5p.js.map +0 -1
- package/dist/core-plugins-CMBv-yVh.cjs +0 -2
- package/dist/core-plugins-CMBv-yVh.cjs.map +0 -1
- package/dist/core-plugins-CqCxLkbd.js +0 -754
- package/dist/core-plugins-CqCxLkbd.js.map +0 -1
- package/dist/core.js +0 -15
- package/dist/core.js.map +0 -1
- package/dist/core.mjs +0 -960
- package/dist/core.mjs.map +0 -1
- package/dist/enhanced-components-BwjBqSA1.js +0 -2858
- package/dist/enhanced-components-BwjBqSA1.js.map +0 -1
- package/dist/enhanced-components-C-ka-XLp.cjs +0 -2
- package/dist/enhanced-components-C-ka-XLp.cjs.map +0 -1
- package/dist/hooks-B-IIWPJr.js +0 -1842
- package/dist/hooks-B-IIWPJr.js.map +0 -1
- package/dist/hooks-DcHzmBwA.cjs +0 -4
- package/dist/hooks-DcHzmBwA.cjs.map +0 -1
- package/dist/minimal-components-BYsMQde5.js +0 -1610
- package/dist/minimal-components-BYsMQde5.js.map +0 -1
- package/dist/minimal-components-CsxQbDp7.cjs +0 -2
- package/dist/minimal-components-CsxQbDp7.cjs.map +0 -1
- package/dist/minimal-components.css +0 -1
- package/dist/mona-loading.gif +0 -0
- package/dist/performance-monitor-DCSijLJg.js +0 -312
- package/dist/performance-monitor-DCSijLJg.js.map +0 -1
- package/dist/performance-monitor-wNFKmqMr.cjs +0 -2
- package/dist/performance-monitor-wNFKmqMr.cjs.map +0 -1
- package/dist/rolldown-runtime-BmowowmI.js +0 -14
- package/dist/rolldown-runtime-mLOUI7ql.cjs +0 -1
- package/dist/utils-D2gQ7c2R.js +0 -64
- package/dist/utils-D2gQ7c2R.js.map +0 -1
- package/dist/utils-DJaAwiZ9.cjs +0 -2
- package/dist/utils-DJaAwiZ9.cjs.map +0 -1
- package/dist/utils.js +0 -1
- package/dist/utils.mjs +0 -3
- package/src/adapters/videojs-adapter.tsx +0 -470
- package/src/assets/mona-loading.gif +0 -0
- package/src/components/AnimateLoading.tsx +0 -111
- package/src/components/LoadingState.tsx +0 -239
- package/src/components/__tests__/media-player-accessibility.test.tsx +0 -510
- package/src/components/__tests__/media-player-react19.test.tsx +0 -457
- package/src/components/accessibility/keyboard-help-overlay.tsx +0 -207
- package/src/components/audio-player.tsx +0 -85
- package/src/components/basic/index.ts +0 -37
- package/src/components/enhanced/advanced-features.tsx +0 -311
- package/src/components/enhanced/debug-panel.tsx +0 -448
- package/src/components/enhanced/enhanced-controls.tsx +0 -597
- package/src/components/enhanced/enhanced-media-player.tsx +0 -566
- package/src/components/enhanced/error-handling.tsx +0 -338
- package/src/components/enhanced/index.ts +0 -39
- package/src/components/enhanced/media-player-enhanced.tsx +0 -383
- package/src/components/examples/basic-video-player.tsx +0 -50
- package/src/components/examples/custom-controls-example.tsx +0 -63
- package/src/components/examples/enhanced-controls-example.tsx +0 -100
- package/src/components/examples/enhanced-media-player-example.tsx +0 -302
- package/src/components/examples/loading-states-demo.tsx +0 -141
- package/src/components/examples/react-19-demo.tsx +0 -349
- package/src/components/examples/volume-orientation-demo.tsx +0 -105
- package/src/components/icon-demo.tsx +0 -196
- package/src/components/legacy.tsx +0 -87
- package/src/components/media-metadata-display.tsx +0 -99
- package/src/components/media-player-audio.tsx +0 -39
- package/src/components/media-player-controls.tsx +0 -223
- package/src/components/media-player-error.tsx +0 -163
- package/src/components/media-player-fullscreen.tsx +0 -109
- package/src/components/media-player-hls.tsx +0 -111
- package/src/components/media-player-loading.tsx +0 -76
- package/src/components/media-player-play.tsx +0 -75
- package/src/components/media-player-root.tsx +0 -338
- package/src/components/media-player-seek.tsx +0 -168
- package/src/components/media-player-time.tsx +0 -99
- package/src/components/media-player-tooltip.tsx +0 -58
- package/src/components/media-player-video.tsx +0 -54
- package/src/components/media-player-volume.tsx +0 -155
- package/src/components/media-player.tsx +0 -292
- package/src/components/media-suspense.tsx +0 -344
- package/src/components/player-settings-form.tsx +0 -158
- package/src/components/react-player-wrapper.tsx +0 -651
- package/src/components/simple-video-player.tsx +0 -62
- package/src/components/ui/blur-poster.tsx +0 -96
- package/src/components/ui/empty-state.tsx +0 -91
- package/src/components/ui/enhanced-seek-bar.tsx +0 -254
- package/src/components/ui/error-state.tsx +0 -124
- package/src/components/ui/fullscreen-button.tsx +0 -81
- package/src/components/ui/loading-skeleton.tsx +0 -107
- package/src/components/ui/media-resource-preloader.tsx +0 -458
- package/src/components/ui/offline-message.tsx +0 -98
- package/src/components/ui/play-button.tsx +0 -99
- package/src/components/ui/seek-bar.tsx +0 -191
- package/src/components/ui/time-display.tsx +0 -61
- package/src/components/ui/volume-control.tsx +0 -190
- package/src/components/unified/base-media-player.tsx +0 -252
- package/src/components/unified/media-player.tsx +0 -75
- package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +0 -587
- package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +0 -573
- package/src/components/variants/minimal/MinimalControls.tsx +0 -124
- package/src/components/variants/minimal/MinimalLoading.tsx +0 -28
- package/src/components/variants/minimal/MinimalMediaPlayer.tsx +0 -318
- package/src/components/variants/minimal/MinimalOverlay.tsx +0 -58
- package/src/components/variants/minimal/MinimalPlayButton.tsx +0 -56
- package/src/components/variants/minimal/MinimalSeekBar.tsx +0 -140
- package/src/components/variants/minimal/MinimalVolumeControl.tsx +0 -75
- package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +0 -206
- package/src/components/variants/minimal/components/CenterPlayButton.tsx +0 -22
- package/src/components/variants/minimal/components/ControlBar.tsx +0 -142
- package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +0 -412
- package/src/components/variants/minimal/components/PlaybackControls.tsx +0 -46
- package/src/components/variants/minimal/components/RightControls.tsx +0 -164
- package/src/components/variants/minimal/components/SeekBar.tsx +0 -127
- package/src/components/variants/minimal/components/SettingsDropdown.tsx +0 -68
- package/src/components/variants/minimal/components/SubtitleDisplay.tsx +0 -21
- package/src/components/variants/minimal/components/TimeDisplay.tsx +0 -15
- package/src/components/variants/minimal/components/VideoElement.tsx +0 -35
- package/src/components/variants/minimal/components/VolumeControl.tsx +0 -220
- package/src/components/variants/minimal/index.ts +0 -23
- package/src/components/video-player.tsx +0 -100
- package/src/context/__tests__/media-store.test.ts +0 -509
- package/src/context/error-handling.ts +0 -398
- package/src/context/media-context.tsx +0 -254
- package/src/context/media-provider.tsx +0 -264
- package/src/context/media-store.ts +0 -387
- package/src/context/persistence.ts +0 -462
- package/src/core/events/event-system.ts +0 -448
- package/src/core/events/hooks.ts +0 -325
- package/src/core/events/index.ts +0 -22
- package/src/core/events/middleware.ts +0 -286
- package/src/core/index.ts +0 -22
- package/src/core/optimization/bundle-optimizer.tsx +0 -312
- package/src/core/performance/cicd.ts +0 -98
- package/src/core/performance/index.ts +0 -38
- package/src/core/performance/media-loading-optimizer.ts +0 -545
- package/src/core/performance/performance-budgets.ts +0 -437
- package/src/core/performance/performance-monitor.tsx +0 -488
- package/src/core/performance/performance-testing.ts +0 -461
- package/src/core/plugins/__tests__/registry.test.ts +0 -595
- package/src/core/plugins/base-plugin.ts +0 -225
- package/src/core/plugins/enhanced-plugin-system.ts +0 -435
- package/src/core/plugins/examples/analytics-plugin.ts +0 -241
- package/src/core/plugins/index.ts +0 -39
- package/src/core/plugins/registry.ts +0 -546
- package/src/core/plugins/types.ts +0 -169
- package/src/core/plugins/utils.ts +0 -317
- package/src/core/progressive-loading.tsx +0 -331
- package/src/core/providers/enhanced-hls-provider.ts +0 -307
- package/src/core/providers/lazy-provider.tsx +0 -14
- package/src/core/providers/service-provider.tsx +0 -164
- package/src/core/utils.tsx +0 -34
- package/src/features/media-session/media-session-manager.ts +0 -411
- package/src/features/picture-in-picture/pip-manager.ts +0 -428
- package/src/features/playlist/playlist-manager.ts +0 -626
- package/src/features/subtitles/subtitle-manager.ts +0 -435
- package/src/features/subtitles/subtitle-parser.ts +0 -284
- package/src/features/thumbnails/thumbnail-generator.ts +0 -528
- package/src/hooks/__tests__/currentTime-fix.test.ts +0 -149
- package/src/hooks/__tests__/use-media-player.test.ts +0 -712
- package/src/hooks/__tests__/use-media-state.test.tsx +0 -316
- package/src/hooks/accessibility/index.ts +0 -27
- package/src/hooks/accessibility/use-accessibility-preferences.ts +0 -190
- package/src/hooks/accessibility/use-focus-management.ts +0 -183
- package/src/hooks/accessibility/use-keyboard-shortcuts.ts +0 -152
- package/src/hooks/accessibility/use-screen-reader.ts +0 -212
- package/src/hooks/core/index.ts +0 -47
- package/src/hooks/legacy.ts +0 -21
- package/src/hooks/use-buffer-health.ts +0 -218
- package/src/hooks/use-enhanced-media-player.ts +0 -575
- package/src/hooks/use-focus-trap.tsx +0 -162
- package/src/hooks/use-intelligent-preloading.ts +0 -387
- package/src/hooks/use-keyboard-controls.ts +0 -115
- package/src/hooks/use-keyboard-shortcuts.ts +0 -255
- package/src/hooks/use-media-actions.ts +0 -184
- package/src/hooks/use-media-metadata.ts +0 -91
- package/src/hooks/use-media-optimistic.ts +0 -264
- package/src/hooks/use-media-player.ts +0 -343
- package/src/hooks/use-media-state.ts +0 -194
- package/src/hooks/use-memory-optimization.ts +0 -360
- package/src/hooks/use-network-status.ts +0 -124
- package/src/hooks/use-optimistic-controls.ts +0 -95
- package/src/hooks/use-optimized-media.ts +0 -283
- package/src/hooks/use-smart-preload.ts +0 -229
- package/src/hooks/use-touch-gestures.ts +0 -461
- package/src/hooks/useEnhancedSubtitles.ts +0 -258
- package/src/hooks/useKeyboardShortcuts.ts +0 -106
- package/src/hooks/useMediaControls.ts +0 -52
- package/src/hooks/useScreenshot.ts +0 -77
- package/src/hooks/useSubtitles.ts +0 -91
- package/src/hooks/useVideoPlayer.ts +0 -278
- package/src/icons/components/FullscreenIcon.tsx +0 -36
- package/src/icons/components/SettingsIcon.tsx +0 -37
- package/src/icons/components/animated/LoadingIcon.tsx +0 -27
- package/src/icons/components/animated/PlayPauseIcon.tsx +0 -42
- package/src/icons/components/media/PauseIcon.tsx +0 -38
- package/src/icons/components/media/PlayIcon.tsx +0 -37
- package/src/icons/components/volume/VolumeIcon.tsx +0 -38
- package/src/icons/components/volume/VolumeOffIcon.tsx +0 -38
- package/src/icons/index.ts +0 -56
- package/src/icons/provider.tsx +0 -58
- package/src/icons/types.ts +0 -60
- package/src/index-enhanced.ts +0 -35
- package/src/index-legacy.ts +0 -324
- package/src/index.css +0 -102
- package/src/lib/__tests__/async-utils.test.ts +0 -291
- package/src/lib/async-utils.ts +0 -194
- package/src/lib/deprecation.ts +0 -51
- package/src/lib/format-time.ts +0 -37
- package/src/lib/index.ts +0 -4
- package/src/lib/utils.ts +0 -6
- package/src/styles/globals.css +0 -462
- package/src/styles/minimal-player.css +0 -621
- package/src/styles/pixel-art.css +0 -41
- package/src/styles/videojs.css +0 -100
- package/src/types/assets.d.ts +0 -29
- package/src/types/events.ts +0 -47
- package/src/types/formats.ts +0 -79
- package/src/types/index.ts +0 -203
- package/src/types/videojs-plugins.d.ts +0 -14
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import React from "react"
|
|
4
|
-
import { useMediaErrorHandler } from "../../context/error-handling"
|
|
5
|
-
import { useOptimisticMediaSelector } from "../../context/media-context"
|
|
6
|
-
import { MediaProvider } from "../../context/media-provider"
|
|
7
|
-
import { useAutoMediaPersistence } from "../../context/persistence"
|
|
8
|
-
import { useMediaActions } from "../../hooks/use-media-actions"
|
|
9
|
-
import { useMediaOptimistic } from "../../hooks/use-media-optimistic"
|
|
10
|
-
import { useEnhancedMediaState } from "../../hooks/use-media-state"
|
|
11
|
-
import { cn } from "../../lib/utils"
|
|
12
|
-
import { MediaPlayerControls } from "../media-player-controls"
|
|
13
|
-
import { MediaPlayerFullscreen } from "../media-player-fullscreen"
|
|
14
|
-
import { MediaPlayerPlay } from "../media-player-play"
|
|
15
|
-
import { MediaPlayerRoot } from "../media-player-root"
|
|
16
|
-
import { MediaPlayerSeek } from "../media-player-seek"
|
|
17
|
-
import { MediaPlayerTime } from "../media-player-time"
|
|
18
|
-
import { MediaPlayerVideo } from "../media-player-video"
|
|
19
|
-
import { MediaPlayerVolume } from "../media-player-volume"
|
|
20
|
-
import {
|
|
21
|
-
EnhancedMediaWrapper,
|
|
22
|
-
MediaLoading,
|
|
23
|
-
useMediaConcurrent,
|
|
24
|
-
useMediaPerformance
|
|
25
|
-
} from "../media-suspense"
|
|
26
|
-
|
|
27
|
-
// Demo component showcasing React 19 features
|
|
28
|
-
interface React19MediaPlayerDemoProps {
|
|
29
|
-
src: string
|
|
30
|
-
poster?: string
|
|
31
|
-
className?: string
|
|
32
|
-
mediaId?: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function React19MediaPlayerDemo({
|
|
36
|
-
src,
|
|
37
|
-
poster,
|
|
38
|
-
className,
|
|
39
|
-
mediaId = "react-19-demo"
|
|
40
|
-
}: React19MediaPlayerDemoProps) {
|
|
41
|
-
return (
|
|
42
|
-
<EnhancedMediaWrapper
|
|
43
|
-
className={className}
|
|
44
|
-
priority="high"
|
|
45
|
-
loadingFallback={<MediaLoading variant="skeleton" size="lg" />}
|
|
46
|
-
errorFallback={ErrorFallback}>
|
|
47
|
-
<MediaProvider
|
|
48
|
-
mediaId={mediaId}
|
|
49
|
-
useEnhancedStore={true}
|
|
50
|
-
enableOptimisticUpdates={true}
|
|
51
|
-
enableErrorRecovery={true}
|
|
52
|
-
persistenceConfig={{
|
|
53
|
-
userPreferences: true,
|
|
54
|
-
sessionState: true,
|
|
55
|
-
debounceMs: 300
|
|
56
|
-
}}
|
|
57
|
-
retryConfig={{
|
|
58
|
-
maxRetries: 3,
|
|
59
|
-
exponentialBackoff: true
|
|
60
|
-
}}>
|
|
61
|
-
<MediaPlayerContent src={src} poster={poster} />
|
|
62
|
-
</MediaProvider>
|
|
63
|
-
</EnhancedMediaWrapper>
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Internal content component with React 19 hooks
|
|
68
|
-
function MediaPlayerContent({ src, poster }: { src: string; poster?: string }) {
|
|
69
|
-
// React 19 enhanced state management
|
|
70
|
-
const mediaState = useEnhancedMediaState()
|
|
71
|
-
const {
|
|
72
|
-
isLoading: actionLoading,
|
|
73
|
-
errorMessage,
|
|
74
|
-
...actions
|
|
75
|
-
} = useMediaActions(
|
|
76
|
-
mediaState.state as any // Type assertion for store
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
// React 19 optimistic updates
|
|
80
|
-
const optimisticState = useMediaOptimistic(mediaState.state as any)
|
|
81
|
-
|
|
82
|
-
// React 19 concurrent features
|
|
83
|
-
const { isPending, updateWithTransition } = useMediaConcurrent()
|
|
84
|
-
|
|
85
|
-
// Performance monitoring
|
|
86
|
-
const { metrics, recordRenderTime } = useMediaPerformance()
|
|
87
|
-
|
|
88
|
-
// Error handling
|
|
89
|
-
const { errors, clearError } = useMediaErrorHandler()
|
|
90
|
-
|
|
91
|
-
// Record render performance
|
|
92
|
-
React.useEffect(() => {
|
|
93
|
-
const start = performance.now()
|
|
94
|
-
return () => recordRenderTime(start)
|
|
95
|
-
}, [recordRenderTime])
|
|
96
|
-
|
|
97
|
-
// Optimistic selectors for immediate UI feedback
|
|
98
|
-
const isPlaying = useOptimisticMediaSelector((state) => state.isPlaying)
|
|
99
|
-
const volume = useOptimisticMediaSelector((state) => state.volume)
|
|
100
|
-
const currentTime = useOptimisticMediaSelector((state) => state.currentTime)
|
|
101
|
-
const duration = useOptimisticMediaSelector((state) => state.duration)
|
|
102
|
-
const isFullscreen = useOptimisticMediaSelector((state) => state.isFullscreen)
|
|
103
|
-
|
|
104
|
-
// Enhanced action handlers with React 19 features
|
|
105
|
-
const handlePlayPause = async () => {
|
|
106
|
-
await updateWithTransition(async () => {
|
|
107
|
-
await optimisticState.togglePlayPause()
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const handleVolumeChange = async (newVolume: number) => {
|
|
112
|
-
await optimisticState.setVolumeOptimistic(newVolume)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const handleSeek = async (time: number) => {
|
|
116
|
-
await optimisticState.seekOptimistic(time)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const handleFullscreenToggle = async () => {
|
|
120
|
-
await optimisticState.toggleFullscreenOptimistic()
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return (
|
|
124
|
-
<MediaPlayerRoot
|
|
125
|
-
className={cn(
|
|
126
|
-
"group relative overflow-hidden rounded-lg",
|
|
127
|
-
"border border-border bg-black shadow-lg",
|
|
128
|
-
"transition-all duration-200",
|
|
129
|
-
isPending && "opacity-75", // Visual feedback for pending transitions
|
|
130
|
-
actionLoading && "pointer-events-none"
|
|
131
|
-
)}
|
|
132
|
-
enableGestures={true}
|
|
133
|
-
enableMobileOptimizations={true}>
|
|
134
|
-
{/* Video Element */}
|
|
135
|
-
<MediaPlayerVideo src={src} poster={poster} className="aspect-video w-full object-contain" />
|
|
136
|
-
|
|
137
|
-
{/* Enhanced Loading State */}
|
|
138
|
-
{(actionLoading || isPending) && (
|
|
139
|
-
<div className="absolute inset-0 flex items-center justify-center bg-black/20">
|
|
140
|
-
<MediaLoading variant="spinner" size="lg">
|
|
141
|
-
{actionLoading ? "Processing..." : "Updating..."}
|
|
142
|
-
</MediaLoading>
|
|
143
|
-
</div>
|
|
144
|
-
)}
|
|
145
|
-
|
|
146
|
-
{/* Controls with React 19 optimizations */}
|
|
147
|
-
<MediaPlayerControls className="absolute right-0 bottom-0 left-0">
|
|
148
|
-
<div className="flex items-center gap-4 bg-gradient-to-t from-black/80 to-transparent p-4">
|
|
149
|
-
{/* Play/Pause with optimistic updates */}
|
|
150
|
-
<MediaPlayerPlay className="text-white transition-colors hover:text-white/80" />
|
|
151
|
-
|
|
152
|
-
{/* Volume with immediate feedback */}
|
|
153
|
-
<MediaPlayerVolume className="text-white" />
|
|
154
|
-
|
|
155
|
-
{/* Time Display with optimistic values */}
|
|
156
|
-
<MediaPlayerTime className="min-w-[120px] font-mono text-sm text-white" />
|
|
157
|
-
|
|
158
|
-
{/* Seek Bar with optimistic scrubbing */}
|
|
159
|
-
<div className="flex-1">
|
|
160
|
-
<MediaPlayerSeek className="w-full" />
|
|
161
|
-
</div>
|
|
162
|
-
|
|
163
|
-
{/* Fullscreen with optimistic updates */}
|
|
164
|
-
<MediaPlayerFullscreen className="text-white transition-colors hover:text-white/80" />
|
|
165
|
-
</div>
|
|
166
|
-
</MediaPlayerControls>
|
|
167
|
-
|
|
168
|
-
{/* Error Display */}
|
|
169
|
-
{(errorMessage || errors.length > 0) && (
|
|
170
|
-
<div className="absolute top-4 right-4 rounded-lg bg-destructive/90 px-3 py-2 text-destructive-foreground text-sm">
|
|
171
|
-
{errorMessage || errors[0]?.message}
|
|
172
|
-
<button
|
|
173
|
-
onClick={() =>
|
|
174
|
-
clearError(errors[0] ? `${errors[0].action?.type}-${errors[0].timestamp}` : "")
|
|
175
|
-
}
|
|
176
|
-
className="ml-2 underline hover:no-underline">
|
|
177
|
-
Dismiss
|
|
178
|
-
</button>
|
|
179
|
-
</div>
|
|
180
|
-
)}
|
|
181
|
-
|
|
182
|
-
{/* Performance Debug Info (Development only) */}
|
|
183
|
-
{process.env.NODE_ENV === "development" && (
|
|
184
|
-
<PerformanceDebugPanel
|
|
185
|
-
metrics={metrics}
|
|
186
|
-
optimisticState={optimisticState}
|
|
187
|
-
errors={errors}
|
|
188
|
-
/>
|
|
189
|
-
)}
|
|
190
|
-
</MediaPlayerRoot>
|
|
191
|
-
)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Error fallback component
|
|
195
|
-
function ErrorFallback({
|
|
196
|
-
error,
|
|
197
|
-
resetError
|
|
198
|
-
}: {
|
|
199
|
-
error: Error
|
|
200
|
-
resetError: () => void
|
|
201
|
-
}) {
|
|
202
|
-
return (
|
|
203
|
-
<div className="flex min-h-[300px] flex-col items-center justify-center rounded-lg border border-destructive/20 bg-destructive/10 p-8">
|
|
204
|
-
<div className="mb-2 font-semibold text-destructive text-xl">React 19 Media Player Error</div>
|
|
205
|
-
<div className="mb-4 max-w-md text-center text-muted-foreground">{error.message}</div>
|
|
206
|
-
<button
|
|
207
|
-
onClick={resetError}
|
|
208
|
-
className="rounded-lg bg-primary px-4 py-2 text-primary-foreground transition-colors hover:bg-primary/90">
|
|
209
|
-
Retry Player
|
|
210
|
-
</button>
|
|
211
|
-
</div>
|
|
212
|
-
)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Performance debug panel (development only)
|
|
216
|
-
function PerformanceDebugPanel({
|
|
217
|
-
metrics,
|
|
218
|
-
optimisticState,
|
|
219
|
-
errors
|
|
220
|
-
}: {
|
|
221
|
-
metrics: any
|
|
222
|
-
optimisticState: any
|
|
223
|
-
errors: any[]
|
|
224
|
-
}) {
|
|
225
|
-
const [isExpanded, setIsExpanded] = React.useState(false)
|
|
226
|
-
|
|
227
|
-
if (!isExpanded) {
|
|
228
|
-
return (
|
|
229
|
-
<button
|
|
230
|
-
onClick={() => setIsExpanded(true)}
|
|
231
|
-
className="absolute top-4 left-4 rounded bg-blue-600 px-2 py-1 text-white text-xs">
|
|
232
|
-
Debug
|
|
233
|
-
</button>
|
|
234
|
-
)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return (
|
|
238
|
-
<div className="absolute top-4 left-4 max-w-sm rounded-lg bg-black/90 p-4 font-mono text-white text-xs">
|
|
239
|
-
<div className="mb-2 flex items-center justify-between">
|
|
240
|
-
<span className="font-bold">React 19 Debug</span>
|
|
241
|
-
<button onClick={() => setIsExpanded(false)} className="text-white/60 hover:text-white">
|
|
242
|
-
×
|
|
243
|
-
</button>
|
|
244
|
-
</div>
|
|
245
|
-
|
|
246
|
-
<div className="space-y-1">
|
|
247
|
-
<div>Render Time: {metrics.renderTime}ms</div>
|
|
248
|
-
<div>Suspense Count: {metrics.suspenseCount}</div>
|
|
249
|
-
<div>Error Count: {metrics.errorCount}</div>
|
|
250
|
-
<div>Transition Count: {metrics.transitionCount}</div>
|
|
251
|
-
<div>Has Optimistic: {optimisticState.hasOptimisticUpdates ? "Yes" : "No"}</div>
|
|
252
|
-
<div>Active Errors: {errors.length}</div>
|
|
253
|
-
</div>
|
|
254
|
-
|
|
255
|
-
{optimisticState.differences?.length > 0 && (
|
|
256
|
-
<div className="mt-2 border-white/20 border-t pt-2">
|
|
257
|
-
<div className="mb-1 font-bold">Optimistic Diffs:</div>
|
|
258
|
-
{optimisticState.differences.map((diff: any, i: number) => (
|
|
259
|
-
<div key={i} className="text-yellow-400">
|
|
260
|
-
{diff.key}: {JSON.stringify(diff.optimistic)}
|
|
261
|
-
(was: {JSON.stringify(diff.actual)})
|
|
262
|
-
</div>
|
|
263
|
-
))}
|
|
264
|
-
</div>
|
|
265
|
-
)}
|
|
266
|
-
</div>
|
|
267
|
-
)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Example usage component
|
|
271
|
-
export function React19DemoExample() {
|
|
272
|
-
const [currentSrc, setCurrentSrc] = React.useState(
|
|
273
|
-
"https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
|
|
274
|
-
)
|
|
275
|
-
|
|
276
|
-
const videoSources = [
|
|
277
|
-
{
|
|
278
|
-
src: "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
|
|
279
|
-
title: "Flower (MDN)"
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
src: "https://www.w3schools.com/html/mov_bbb.mp4",
|
|
283
|
-
title: "Big Buck Bunny"
|
|
284
|
-
}
|
|
285
|
-
]
|
|
286
|
-
|
|
287
|
-
const currentVideo = videoSources.find((v) => v.src === currentSrc)!
|
|
288
|
-
|
|
289
|
-
return (
|
|
290
|
-
<div className="mx-auto max-w-4xl space-y-6 p-6">
|
|
291
|
-
<div>
|
|
292
|
-
<h1 className="mb-2 font-bold text-3xl">React 19 Enhanced Media Player</h1>
|
|
293
|
-
<p className="text-muted-foreground">
|
|
294
|
-
Featuring useOptimistic, useActionState, Suspense, concurrent features, error handling,
|
|
295
|
-
state persistence, and performance optimizations.
|
|
296
|
-
</p>
|
|
297
|
-
</div>
|
|
298
|
-
|
|
299
|
-
{/* Video Source Selector */}
|
|
300
|
-
<div className="flex gap-4">
|
|
301
|
-
{videoSources.map((video) => (
|
|
302
|
-
<button
|
|
303
|
-
key={video.src}
|
|
304
|
-
onClick={() => setCurrentSrc(video.src)}
|
|
305
|
-
className={cn(
|
|
306
|
-
"rounded-lg border px-4 py-2 transition-colors",
|
|
307
|
-
currentSrc === video.src
|
|
308
|
-
? "border-primary bg-primary text-primary-foreground"
|
|
309
|
-
: "border-border bg-background hover:border-primary/50"
|
|
310
|
-
)}>
|
|
311
|
-
{video.title}
|
|
312
|
-
</button>
|
|
313
|
-
))}
|
|
314
|
-
</div>
|
|
315
|
-
|
|
316
|
-
{/* Enhanced Media Player */}
|
|
317
|
-
<React19MediaPlayerDemo
|
|
318
|
-
src={currentSrc}
|
|
319
|
-
poster={undefined}
|
|
320
|
-
mediaId={`demo-${currentSrc}`}
|
|
321
|
-
className="w-full"
|
|
322
|
-
/>
|
|
323
|
-
|
|
324
|
-
{/* Feature List */}
|
|
325
|
-
<div className="grid grid-cols-1 gap-4 text-sm md:grid-cols-2">
|
|
326
|
-
<div className="space-y-2">
|
|
327
|
-
<h3 className="font-semibold">React 19 Features</h3>
|
|
328
|
-
<ul className="space-y-1 text-muted-foreground">
|
|
329
|
-
<li>✅ useOptimistic for immediate UI feedback</li>
|
|
330
|
-
<li>✅ useActionState for form-like actions</li>
|
|
331
|
-
<li>✅ Automatic memoization via React compiler</li>
|
|
332
|
-
<li>✅ Concurrent features with Suspense</li>
|
|
333
|
-
<li>✅ Enhanced error boundaries</li>
|
|
334
|
-
</ul>
|
|
335
|
-
</div>
|
|
336
|
-
<div className="space-y-2">
|
|
337
|
-
<h3 className="font-semibold">Media Features</h3>
|
|
338
|
-
<ul className="space-y-1 text-muted-foreground">
|
|
339
|
-
<li>✅ Optimistic play/pause/seek/volume</li>
|
|
340
|
-
<li>✅ Automatic state persistence</li>
|
|
341
|
-
<li>✅ Error recovery with retries</li>
|
|
342
|
-
<li>✅ Touch gestures & mobile optimization</li>
|
|
343
|
-
<li>✅ Performance monitoring</li>
|
|
344
|
-
</ul>
|
|
345
|
-
</div>
|
|
346
|
-
</div>
|
|
347
|
-
</div>
|
|
348
|
-
)
|
|
349
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { useState } from "react"
|
|
4
|
-
import { SimpleMinimalPlayer } from "../variants/minimal/SimpleMinimalPlayer"
|
|
5
|
-
|
|
6
|
-
export function VolumeOrientationDemo() {
|
|
7
|
-
const [orientation, setOrientation] = useState<"horizontal" | "vertical">("horizontal")
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<div className="min-h-screen bg-gray-950 p-8">
|
|
11
|
-
<div className="mx-auto max-w-5xl space-y-8">
|
|
12
|
-
<div className="text-center">
|
|
13
|
-
<h1 className="mb-4 font-bold text-3xl text-white">Enhanced Volume Control Demo</h1>
|
|
14
|
-
<p className="mb-6 text-gray-400">
|
|
15
|
-
Small gradient volume slider with horizontal/vertical orientation
|
|
16
|
-
</p>
|
|
17
|
-
|
|
18
|
-
{/* Orientation toggle */}
|
|
19
|
-
<div className="mb-8 flex justify-center gap-4">
|
|
20
|
-
<button
|
|
21
|
-
onClick={() => setOrientation("horizontal")}
|
|
22
|
-
className={`rounded-lg px-4 py-2 transition-colors ${
|
|
23
|
-
orientation === "horizontal"
|
|
24
|
-
? "bg-cyan-600 text-white"
|
|
25
|
-
: "bg-gray-800 text-gray-400 hover:bg-gray-700"
|
|
26
|
-
}`}>
|
|
27
|
-
Horizontal (Default)
|
|
28
|
-
</button>
|
|
29
|
-
<button
|
|
30
|
-
onClick={() => setOrientation("vertical")}
|
|
31
|
-
className={`rounded-lg px-4 py-2 transition-colors ${
|
|
32
|
-
orientation === "vertical"
|
|
33
|
-
? "bg-cyan-600 text-white"
|
|
34
|
-
: "bg-gray-800 text-gray-400 hover:bg-gray-700"
|
|
35
|
-
}`}>
|
|
36
|
-
Vertical
|
|
37
|
-
</button>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
{/* Demo Player */}
|
|
42
|
-
<div className="aspect-video overflow-hidden rounded-lg bg-black">
|
|
43
|
-
<SimpleMinimalPlayer
|
|
44
|
-
src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
|
|
45
|
-
crossOrigin="anonymous"
|
|
46
|
-
className="h-full w-full"
|
|
47
|
-
volumeOrientation={orientation}
|
|
48
|
-
/>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
{/* Features list */}
|
|
52
|
-
<div className="mt-8 grid gap-6 md:grid-cols-2">
|
|
53
|
-
<div className="rounded-lg bg-gray-900 p-6">
|
|
54
|
-
<h3 className="mb-3 font-semibold text-lg text-white">Horizontal Mode (Default)</h3>
|
|
55
|
-
<ul className="space-y-2 text-gray-400 text-sm">
|
|
56
|
-
<li>• Slider appears beside the volume button</li>
|
|
57
|
-
<li>• Expands horizontally on hover</li>
|
|
58
|
-
<li>• Cyan to blue gradient (4px height)</li>
|
|
59
|
-
<li>• Smooth 300ms transition</li>
|
|
60
|
-
<li>• White thumb appears on hover</li>
|
|
61
|
-
</ul>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<div className="rounded-lg bg-gray-900 p-6">
|
|
65
|
-
<h3 className="mb-3 font-semibold text-lg text-white">Vertical Mode</h3>
|
|
66
|
-
<ul className="space-y-2 text-gray-400 text-sm">
|
|
67
|
-
<li>• Slider appears above the volume button</li>
|
|
68
|
-
<li>• Expands vertically on hover</li>
|
|
69
|
-
<li>• Same gradient rotated 90°</li>
|
|
70
|
-
<li>• Shows percentage value</li>
|
|
71
|
-
<li>• Dark backdrop for visibility</li>
|
|
72
|
-
</ul>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
{/* Code example */}
|
|
77
|
-
<div className="rounded-lg bg-gray-900 p-6">
|
|
78
|
-
<h3 className="mb-3 font-semibold text-lg text-white">Usage Example</h3>
|
|
79
|
-
<pre className="overflow-x-auto text-gray-300 text-sm">
|
|
80
|
-
<code>{`// Default horizontal orientation
|
|
81
|
-
<VolumeControl
|
|
82
|
-
volume={volume}
|
|
83
|
-
isMuted={isMuted}
|
|
84
|
-
showVolumeSlider={showSlider}
|
|
85
|
-
onToggleMute={handleMute}
|
|
86
|
-
onVolumeChange={handleVolumeChange}
|
|
87
|
-
onShowVolumeSlider={setShowSlider}
|
|
88
|
-
/>
|
|
89
|
-
|
|
90
|
-
// Vertical orientation
|
|
91
|
-
<VolumeControl
|
|
92
|
-
volume={volume}
|
|
93
|
-
isMuted={isMuted}
|
|
94
|
-
showVolumeSlider={showSlider}
|
|
95
|
-
onToggleMute={handleMute}
|
|
96
|
-
onVolumeChange={handleVolumeChange}
|
|
97
|
-
onShowVolumeSlider={setShowSlider}
|
|
98
|
-
orientation="vertical"
|
|
99
|
-
/>`}</code>
|
|
100
|
-
</pre>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
)
|
|
105
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { useState } from "react"
|
|
2
|
-
import {
|
|
3
|
-
FullscreenIcon,
|
|
4
|
-
IconProvider,
|
|
5
|
-
LoadingIcon,
|
|
6
|
-
PauseIcon,
|
|
7
|
-
PlayIcon,
|
|
8
|
-
PlayPauseIcon,
|
|
9
|
-
SettingsIcon,
|
|
10
|
-
VolumeIcon,
|
|
11
|
-
VolumeOffIcon
|
|
12
|
-
} from "../icons"
|
|
13
|
-
|
|
14
|
-
export function IconSystemDemo() {
|
|
15
|
-
const [isPlaying, setIsPlaying] = useState(false)
|
|
16
|
-
const [volume, setVolume] = useState(0.8)
|
|
17
|
-
const [theme, setTheme] = useState({
|
|
18
|
-
size: 24,
|
|
19
|
-
strokeWidth: 2,
|
|
20
|
-
color: "currentColor"
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const customPlayIcon = ({ className, ...props }: any) => (
|
|
24
|
-
<svg className={className} width="24" height="24" viewBox="0 0 24 24" fill="none" {...props}>
|
|
25
|
-
<circle cx="12" cy="12" r="10" fill="#ff6b6b" />
|
|
26
|
-
<polygon points="10 8 16 12 10 16 10 8" fill="white" />
|
|
27
|
-
</svg>
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<div className="min-h-screen bg-gray-950 p-8">
|
|
32
|
-
<div className="mx-auto max-w-4xl">
|
|
33
|
-
<h1 className="mb-8 text-center font-bold text-3xl text-white">Icon System Demo</h1>
|
|
34
|
-
|
|
35
|
-
{/* Theme Controls */}
|
|
36
|
-
<div className="mb-8 rounded-lg bg-gray-800 p-6">
|
|
37
|
-
<h2 className="mb-4 font-semibold text-white text-xl">Theme Configuration</h2>
|
|
38
|
-
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
39
|
-
<div>
|
|
40
|
-
<label className="mb-2 block font-medium text-sm text-white">
|
|
41
|
-
Size: {theme.size}
|
|
42
|
-
</label>
|
|
43
|
-
<input
|
|
44
|
-
type="range"
|
|
45
|
-
min="16"
|
|
46
|
-
max="48"
|
|
47
|
-
value={theme.size}
|
|
48
|
-
onChange={(e) => setTheme((prev) => ({ ...prev, size: Number(e.target.value) }))}
|
|
49
|
-
className="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-700"
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
<div>
|
|
53
|
-
<label className="mb-2 block font-medium text-sm text-white">
|
|
54
|
-
Stroke Width: {theme.strokeWidth}
|
|
55
|
-
</label>
|
|
56
|
-
<input
|
|
57
|
-
type="range"
|
|
58
|
-
min="1"
|
|
59
|
-
max="4"
|
|
60
|
-
step="0.5"
|
|
61
|
-
value={theme.strokeWidth}
|
|
62
|
-
onChange={(e) =>
|
|
63
|
-
setTheme((prev) => ({ ...prev, strokeWidth: Number(e.target.value) }))
|
|
64
|
-
}
|
|
65
|
-
className="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-700"
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
68
|
-
<div>
|
|
69
|
-
<label className="mb-2 block font-medium text-sm text-white">Color</label>
|
|
70
|
-
<select
|
|
71
|
-
value={theme.color}
|
|
72
|
-
onChange={(e) => setTheme((prev) => ({ ...prev, color: e.target.value }))}
|
|
73
|
-
className="w-full rounded-lg border border-gray-600 bg-gray-700 p-2 text-white">
|
|
74
|
-
<option value="currentColor">Current Color</option>
|
|
75
|
-
<option value="#ffffff">White</option>
|
|
76
|
-
<option value="#06b6d4">Cyan</option>
|
|
77
|
-
<option value="#f59e0b">Amber</option>
|
|
78
|
-
<option value="#ef4444">Red</option>
|
|
79
|
-
</select>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
|
|
84
|
-
<div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
|
|
85
|
-
{/* Default Icons */}
|
|
86
|
-
<div className="rounded-lg bg-gray-800 p-6">
|
|
87
|
-
<h2 className="mb-4 font-semibold text-white text-xl">Default Icons</h2>
|
|
88
|
-
<IconProvider theme={theme}>
|
|
89
|
-
<div className="grid grid-cols-4 gap-4 text-white">
|
|
90
|
-
<div className="flex flex-col items-center space-y-2">
|
|
91
|
-
<PlayIcon />
|
|
92
|
-
<span className="text-xs">Play</span>
|
|
93
|
-
</div>
|
|
94
|
-
<div className="flex flex-col items-center space-y-2">
|
|
95
|
-
<PauseIcon />
|
|
96
|
-
<span className="text-xs">Pause</span>
|
|
97
|
-
</div>
|
|
98
|
-
<div className="flex flex-col items-center space-y-2">
|
|
99
|
-
<VolumeIcon />
|
|
100
|
-
<span className="text-xs">Volume</span>
|
|
101
|
-
</div>
|
|
102
|
-
<div className="flex flex-col items-center space-y-2">
|
|
103
|
-
<VolumeOffIcon />
|
|
104
|
-
<span className="text-xs">Mute</span>
|
|
105
|
-
</div>
|
|
106
|
-
<div className="flex flex-col items-center space-y-2">
|
|
107
|
-
<SettingsIcon />
|
|
108
|
-
<span className="text-xs">Settings</span>
|
|
109
|
-
</div>
|
|
110
|
-
<div className="flex flex-col items-center space-y-2">
|
|
111
|
-
<FullscreenIcon />
|
|
112
|
-
<span className="text-xs">Fullscreen</span>
|
|
113
|
-
</div>
|
|
114
|
-
<div className="flex flex-col items-center space-y-2">
|
|
115
|
-
<LoadingIcon />
|
|
116
|
-
<span className="text-xs">Loading</span>
|
|
117
|
-
</div>
|
|
118
|
-
<div className="flex flex-col items-center space-y-2">
|
|
119
|
-
<PlayPauseIcon isPlaying={isPlaying} />
|
|
120
|
-
<span className="text-xs">Play/Pause</span>
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
</IconProvider>
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
{/* Custom Icons */}
|
|
127
|
-
<div className="rounded-lg bg-gray-800 p-6">
|
|
128
|
-
<h2 className="mb-4 font-semibold text-white text-xl">Custom Icons</h2>
|
|
129
|
-
<IconProvider
|
|
130
|
-
theme={theme}
|
|
131
|
-
icons={{
|
|
132
|
-
play: customPlayIcon
|
|
133
|
-
}}>
|
|
134
|
-
<div className="grid grid-cols-4 gap-4 text-white">
|
|
135
|
-
<div className="flex flex-col items-center space-y-2">
|
|
136
|
-
<PlayIcon />
|
|
137
|
-
<span className="text-xs">Custom Play</span>
|
|
138
|
-
</div>
|
|
139
|
-
<div className="flex flex-col items-center space-y-2">
|
|
140
|
-
<PauseIcon />
|
|
141
|
-
<span className="text-xs">Default Pause</span>
|
|
142
|
-
</div>
|
|
143
|
-
<div className="flex flex-col items-center space-y-2">
|
|
144
|
-
<VolumeIcon />
|
|
145
|
-
<span className="text-xs">Default Volume</span>
|
|
146
|
-
</div>
|
|
147
|
-
<div className="flex flex-col items-center space-y-2">
|
|
148
|
-
<SettingsIcon />
|
|
149
|
-
<span className="text-xs">Default Settings</span>
|
|
150
|
-
</div>
|
|
151
|
-
</div>
|
|
152
|
-
</IconProvider>
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
|
|
156
|
-
{/* Interactive Demo */}
|
|
157
|
-
<div className="mt-8 rounded-lg bg-gray-800 p-6">
|
|
158
|
-
<h2 className="mb-4 font-semibold text-white text-xl">Interactive Media Player Demo</h2>
|
|
159
|
-
<IconProvider theme={{ ...theme, size: 32 }}>
|
|
160
|
-
<div className="flex items-center justify-center space-x-6 text-white">
|
|
161
|
-
<button
|
|
162
|
-
onClick={() => setIsPlaying(!isPlaying)}
|
|
163
|
-
className="rounded-full bg-blue-600 p-3 transition-colors hover:bg-blue-700"
|
|
164
|
-
aria-label={isPlaying ? "Pause" : "Play"}>
|
|
165
|
-
<PlayPauseIcon isPlaying={isPlaying} />
|
|
166
|
-
</button>
|
|
167
|
-
|
|
168
|
-
<button
|
|
169
|
-
onClick={() => setVolume(volume > 0 ? 0 : 0.8)}
|
|
170
|
-
className="rounded-full bg-gray-600 p-3 transition-colors hover:bg-gray-700"
|
|
171
|
-
aria-label={volume > 0 ? "Mute" : "Unmute"}>
|
|
172
|
-
{volume > 0 ? <VolumeIcon /> : <VolumeOffIcon />}
|
|
173
|
-
</button>
|
|
174
|
-
|
|
175
|
-
<button
|
|
176
|
-
className="rounded-full bg-gray-600 p-3 transition-colors hover:bg-gray-700"
|
|
177
|
-
aria-label="Settings">
|
|
178
|
-
<SettingsIcon />
|
|
179
|
-
</button>
|
|
180
|
-
|
|
181
|
-
<button
|
|
182
|
-
className="rounded-full bg-gray-600 p-3 transition-colors hover:bg-gray-700"
|
|
183
|
-
aria-label="Fullscreen">
|
|
184
|
-
<FullscreenIcon />
|
|
185
|
-
</button>
|
|
186
|
-
</div>
|
|
187
|
-
</IconProvider>
|
|
188
|
-
|
|
189
|
-
<div className="mt-4 text-center text-gray-400 text-sm">
|
|
190
|
-
Status: {isPlaying ? "Playing" : "Paused"} | Volume: {volume > 0 ? "On" : "Muted"}
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
)
|
|
196
|
-
}
|