@videojs/react 10.0.0-beta.8 → 10.0.0-beta.9

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 (118) hide show
  1. package/dist/default/media/simple-hls-video/index.js.map +1 -1
  2. package/dist/default/presets/audio/minimal-skin.css +161 -141
  3. package/dist/default/presets/audio/minimal-skin.js +110 -100
  4. package/dist/default/presets/audio/minimal-skin.js.map +1 -1
  5. package/dist/default/presets/audio/minimal-skin.tailwind.js +120 -111
  6. package/dist/default/presets/audio/minimal-skin.tailwind.js.map +1 -1
  7. package/dist/default/presets/audio/skin.css +164 -132
  8. package/dist/default/presets/audio/skin.js +101 -91
  9. package/dist/default/presets/audio/skin.js.map +1 -1
  10. package/dist/default/presets/audio/skin.tailwind.js +111 -102
  11. package/dist/default/presets/audio/skin.tailwind.js.map +1 -1
  12. package/dist/default/presets/{video/error-dialog.js → error-dialog.js} +18 -18
  13. package/dist/default/presets/error-dialog.js.map +1 -0
  14. package/dist/default/presets/video/minimal-skin.css +224 -192
  15. package/dist/default/presets/video/minimal-skin.js +58 -62
  16. package/dist/default/presets/video/minimal-skin.js.map +1 -1
  17. package/dist/default/presets/video/minimal-skin.tailwind.js +70 -78
  18. package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
  19. package/dist/default/presets/video/skin.css +238 -189
  20. package/dist/default/presets/video/skin.js +58 -62
  21. package/dist/default/presets/video/skin.js.map +1 -1
  22. package/dist/default/presets/video/skin.tailwind.js +69 -77
  23. package/dist/default/presets/video/skin.tailwind.js.map +1 -1
  24. package/dist/default/skins/dist/default/default/tailwind/audio.tailwind.js +5 -4
  25. package/dist/default/skins/dist/default/default/tailwind/audio.tailwind.js.map +1 -1
  26. package/dist/default/skins/dist/default/default/tailwind/components/button.js +4 -3
  27. package/dist/default/skins/dist/default/default/tailwind/components/button.js.map +1 -1
  28. package/dist/default/skins/dist/default/default/tailwind/components/error.js +2 -2
  29. package/dist/default/skins/dist/default/default/tailwind/components/error.js.map +1 -1
  30. package/dist/default/skins/dist/default/default/tailwind/components/overlay.js +1 -1
  31. package/dist/default/skins/dist/default/default/tailwind/components/overlay.js.map +1 -1
  32. package/dist/default/skins/dist/default/default/tailwind/components/popup.js +1 -1
  33. package/dist/default/skins/dist/default/default/tailwind/components/popup.js.map +1 -1
  34. package/dist/default/skins/dist/default/default/tailwind/components/seek.js +1 -1
  35. package/dist/default/skins/dist/default/default/tailwind/components/seek.js.map +1 -1
  36. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js +5 -3
  37. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  38. package/dist/default/skins/dist/default/minimal/tailwind/audio.tailwind.js +9 -4
  39. package/dist/default/skins/dist/default/minimal/tailwind/audio.tailwind.js.map +1 -1
  40. package/dist/default/skins/dist/default/minimal/tailwind/components/button.js +4 -3
  41. package/dist/default/skins/dist/default/minimal/tailwind/components/button.js.map +1 -1
  42. package/dist/default/skins/dist/default/minimal/tailwind/components/error.js +2 -2
  43. package/dist/default/skins/dist/default/minimal/tailwind/components/error.js.map +1 -1
  44. package/dist/default/skins/dist/default/minimal/tailwind/components/overlay.js +1 -1
  45. package/dist/default/skins/dist/default/minimal/tailwind/components/overlay.js.map +1 -1
  46. package/dist/default/skins/dist/default/minimal/tailwind/components/popup.js +1 -1
  47. package/dist/default/skins/dist/default/minimal/tailwind/components/popup.js.map +1 -1
  48. package/dist/default/skins/dist/default/minimal/tailwind/components/root.js +1 -1
  49. package/dist/default/skins/dist/default/minimal/tailwind/components/root.js.map +1 -1
  50. package/dist/default/skins/dist/default/minimal/tailwind/components/seek.js +1 -1
  51. package/dist/default/skins/dist/default/minimal/tailwind/components/seek.js.map +1 -1
  52. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js +10 -4
  53. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  54. package/dist/dev/media/simple-hls-video/index.d.ts.map +1 -1
  55. package/dist/dev/media/simple-hls-video/index.js.map +1 -1
  56. package/dist/dev/presets/audio/minimal-skin.css +161 -141
  57. package/dist/dev/presets/audio/minimal-skin.d.ts.map +1 -1
  58. package/dist/dev/presets/audio/minimal-skin.js +110 -100
  59. package/dist/dev/presets/audio/minimal-skin.js.map +1 -1
  60. package/dist/dev/presets/audio/minimal-skin.tailwind.d.ts.map +1 -1
  61. package/dist/dev/presets/audio/minimal-skin.tailwind.js +120 -111
  62. package/dist/dev/presets/audio/minimal-skin.tailwind.js.map +1 -1
  63. package/dist/dev/presets/audio/skin.css +164 -132
  64. package/dist/dev/presets/audio/skin.d.ts.map +1 -1
  65. package/dist/dev/presets/audio/skin.js +101 -91
  66. package/dist/dev/presets/audio/skin.js.map +1 -1
  67. package/dist/dev/presets/audio/skin.tailwind.d.ts.map +1 -1
  68. package/dist/dev/presets/audio/skin.tailwind.js +111 -102
  69. package/dist/dev/presets/audio/skin.tailwind.js.map +1 -1
  70. package/dist/dev/presets/{video/error-dialog.js → error-dialog.js} +18 -18
  71. package/dist/dev/presets/error-dialog.js.map +1 -0
  72. package/dist/dev/presets/video/minimal-skin.css +224 -192
  73. package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
  74. package/dist/dev/presets/video/minimal-skin.js +58 -62
  75. package/dist/dev/presets/video/minimal-skin.js.map +1 -1
  76. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
  77. package/dist/dev/presets/video/minimal-skin.tailwind.js +70 -78
  78. package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
  79. package/dist/dev/presets/video/skin.css +238 -189
  80. package/dist/dev/presets/video/skin.d.ts.map +1 -1
  81. package/dist/dev/presets/video/skin.js +58 -62
  82. package/dist/dev/presets/video/skin.js.map +1 -1
  83. package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
  84. package/dist/dev/presets/video/skin.tailwind.js +69 -77
  85. package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
  86. package/dist/dev/skins/dist/default/default/tailwind/audio.tailwind.js +5 -4
  87. package/dist/dev/skins/dist/default/default/tailwind/audio.tailwind.js.map +1 -1
  88. package/dist/dev/skins/dist/default/default/tailwind/components/button.js +4 -3
  89. package/dist/dev/skins/dist/default/default/tailwind/components/button.js.map +1 -1
  90. package/dist/dev/skins/dist/default/default/tailwind/components/error.js +2 -2
  91. package/dist/dev/skins/dist/default/default/tailwind/components/error.js.map +1 -1
  92. package/dist/dev/skins/dist/default/default/tailwind/components/overlay.js +1 -1
  93. package/dist/dev/skins/dist/default/default/tailwind/components/overlay.js.map +1 -1
  94. package/dist/dev/skins/dist/default/default/tailwind/components/popup.js +1 -1
  95. package/dist/dev/skins/dist/default/default/tailwind/components/popup.js.map +1 -1
  96. package/dist/dev/skins/dist/default/default/tailwind/components/seek.js +1 -1
  97. package/dist/dev/skins/dist/default/default/tailwind/components/seek.js.map +1 -1
  98. package/dist/dev/skins/dist/default/default/tailwind/video.tailwind.js +5 -3
  99. package/dist/dev/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  100. package/dist/dev/skins/dist/default/minimal/tailwind/audio.tailwind.js +9 -4
  101. package/dist/dev/skins/dist/default/minimal/tailwind/audio.tailwind.js.map +1 -1
  102. package/dist/dev/skins/dist/default/minimal/tailwind/components/button.js +4 -3
  103. package/dist/dev/skins/dist/default/minimal/tailwind/components/button.js.map +1 -1
  104. package/dist/dev/skins/dist/default/minimal/tailwind/components/error.js +2 -2
  105. package/dist/dev/skins/dist/default/minimal/tailwind/components/error.js.map +1 -1
  106. package/dist/dev/skins/dist/default/minimal/tailwind/components/overlay.js +1 -1
  107. package/dist/dev/skins/dist/default/minimal/tailwind/components/overlay.js.map +1 -1
  108. package/dist/dev/skins/dist/default/minimal/tailwind/components/popup.js +1 -1
  109. package/dist/dev/skins/dist/default/minimal/tailwind/components/popup.js.map +1 -1
  110. package/dist/dev/skins/dist/default/minimal/tailwind/components/root.js +1 -1
  111. package/dist/dev/skins/dist/default/minimal/tailwind/components/root.js.map +1 -1
  112. package/dist/dev/skins/dist/default/minimal/tailwind/components/seek.js +1 -1
  113. package/dist/dev/skins/dist/default/minimal/tailwind/components/seek.js.map +1 -1
  114. package/dist/dev/skins/dist/default/minimal/tailwind/video.tailwind.js +10 -4
  115. package/dist/dev/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  116. package/package.json +7 -7
  117. package/dist/default/presets/video/error-dialog.js.map +0 -1
  118. package/dist/dev/presets/video/error-dialog.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"minimal-skin.tailwind.js","names":["Popover.Root","Popover.Trigger","Popover.Popup","VolumeSlider.Root","VolumeSlider.Track","VolumeSlider.Fill","VolumeSlider.Thumb","Controls.Root","Tooltip.Provider","Tooltip.Root","Tooltip.Trigger","Tooltip.Popup","Time.Group","Time.Value","Time.Separator","TimeSlider.Root","TimeSlider.Track","TimeSlider.Fill","TimeSlider.Buffer","TimeSlider.Thumb","Slider.Thumbnail","TimeSlider.Value"],"sources":["../../../../src/presets/video/minimal-skin.tailwind.tsx"],"sourcesContent":["import {\n CaptionsOffIcon,\n CaptionsOnIcon,\n FullscreenEnterIcon,\n FullscreenExitIcon,\n PauseIcon,\n PipEnterIcon,\n PipExitIcon,\n PlayIcon,\n RestartIcon,\n SeekIcon,\n SpinnerIcon,\n VolumeHighIcon,\n VolumeLowIcon,\n VolumeOffIcon,\n} from '@videojs/icons/react/minimal';\nimport { playbackRate } from '@videojs/skins/default/tailwind/video.tailwind';\nimport {\n bufferingIndicator,\n button,\n buttonGroup,\n controls,\n error,\n icon,\n iconContainer,\n iconFlipped,\n iconState,\n overlay,\n popup,\n poster,\n preview,\n root,\n seek,\n slider,\n time,\n} from '@videojs/skins/minimal/tailwind/video.tailwind';\nimport { isString } from '@videojs/utils/predicate';\nimport { cn } from '@videojs/utils/style';\nimport { type ComponentProps, forwardRef, type ReactNode } from 'react';\nimport { Container, usePlayer } from '@/player/context';\nimport { BufferingIndicator } from '@/ui/buffering-indicator';\nimport { CaptionsButton } from '@/ui/captions-button';\nimport { Controls } from '@/ui/controls';\nimport { FullscreenButton } from '@/ui/fullscreen-button';\nimport { MuteButton } from '@/ui/mute-button';\nimport { PiPButton } from '@/ui/pip-button';\nimport { PlayButton } from '@/ui/play-button';\nimport { PlaybackRateButton } from '@/ui/playback-rate-button';\nimport { Popover } from '@/ui/popover';\nimport { Poster } from '@/ui/poster';\nimport { SeekButton } from '@/ui/seek-button';\nimport { Slider } from '@/ui/slider';\nimport { Time } from '@/ui/time';\nimport { TimeSlider } from '@/ui/time-slider';\nimport { Tooltip } from '@/ui/tooltip';\nimport { VolumeSlider } from '@/ui/volume-slider';\nimport { isRenderProp } from '@/utils/use-render';\nimport { ErrorDialog } from './error-dialog';\nimport type { MinimalVideoSkinProps } from './minimal-skin';\n\nconst SEEK_TIME = 10;\n\n/* --------------------------------------- Components ---------------------------------------- */\n\nconst Button = forwardRef<HTMLButtonElement, ComponentProps<'button'> & { variant?: 'icon' }>(function Button(\n { className, variant, ...props },\n ref\n) {\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(button.base, variant === 'icon' ? button.icon : button.default, className)}\n {...props}\n />\n );\n});\n\nconst SliderRoot = forwardRef<HTMLDivElement, ComponentProps<'div'>>(function SliderRoot({ className, ...props }, ref) {\n return <div ref={ref} className={cn(slider.root, className)} {...props} />;\n});\n\nconst SliderTrack = forwardRef<HTMLDivElement, ComponentProps<'div'>>(function SliderTrack(\n { className, ...props },\n ref\n) {\n return <div ref={ref} className={cn(slider.track, className)} {...props} />;\n});\n\nconst SliderFill = forwardRef<HTMLDivElement, ComponentProps<'div'> & { type?: 'fill' | 'buffer' }>(function SliderFill(\n { type = 'fill', className, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n className={cn(slider.fill.base, type === 'fill' ? slider.fill.fill : slider.fill.buffer, className)}\n {...props}\n />\n );\n});\n\nconst SliderThumb = forwardRef<HTMLDivElement, ComponentProps<'div'> & { persistent?: boolean }>(function SliderThumb(\n { persistent, className, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n className={cn(slider.thumb.base, persistent ? undefined : slider.thumb.interactive, className)}\n {...props}\n />\n );\n});\n\nconst errorClasses = {\n root: error.root,\n dialog: error.dialog,\n content: error.content,\n title: error.title,\n actions: error.actions,\n close: cn(button.base, button.default),\n};\n\nfunction PlayLabel(): ReactNode {\n const paused = usePlayer((s) => Boolean(s.paused));\n const ended = usePlayer((s) => Boolean(s.ended));\n if (ended) return <>Replay</>;\n return paused ? <>Play</> : <>Pause</>;\n}\n\nfunction CaptionsLabel(): ReactNode {\n const active = usePlayer((s) => Boolean(s.subtitlesShowing));\n return active ? <>Disable captions</> : <>Enable captions</>;\n}\n\nfunction PiPLabel(): ReactNode {\n const pip = usePlayer((s) => Boolean(s.pip));\n return pip ? <>Exit picture-in-picture</> : <>Enter picture-in-picture</>;\n}\n\nfunction FullscreenLabel(): ReactNode {\n const fullscreen = usePlayer((s) => Boolean(s.fullscreen));\n return fullscreen ? <>Exit fullscreen</> : <>Enter fullscreen</>;\n}\n\nfunction VolumePopover(): ReactNode {\n const volumeUnsupported = usePlayer((s) => s.volumeAvailability === 'unsupported');\n\n const muteButton = (\n <MuteButton\n render={(props) => (\n <Button variant=\"icon\" {...props} className={iconState.mute.button}>\n <VolumeOffIcon className={cn(icon, iconState.mute.volumeOff)} />\n <VolumeLowIcon className={cn(icon, iconState.mute.volumeLow)} />\n <VolumeHighIcon className={cn(icon, iconState.mute.volumeHigh)} />\n </Button>\n )}\n />\n );\n\n if (volumeUnsupported) return muteButton;\n\n return (\n <Popover.Root openOnHover delay={200} closeDelay={100} side=\"top\">\n <Popover.Trigger render={muteButton} />\n <Popover.Popup className={cn(popup.volume)}>\n <VolumeSlider.Root orientation=\"vertical\" thumbAlignment=\"edge\" render={(props) => <SliderRoot {...props} />}>\n <VolumeSlider.Track render={(props) => <SliderTrack {...props} />}>\n <VolumeSlider.Fill render={(props) => <SliderFill {...props} />} />\n </VolumeSlider.Track>\n <VolumeSlider.Thumb render={(props) => <SliderThumb persistent {...props} />} />\n </VolumeSlider.Root>\n </Popover.Popup>\n </Popover.Root>\n );\n}\n\n/* ------------------------------------------ Skin ------------------------------------------- */\n\nexport function MinimalVideoSkinTailwind(props: MinimalVideoSkinProps): ReactNode {\n const { children, className, poster: posterProp, ...rest } = props;\n\n return (\n <Container className={cn(root(false), className)} {...rest}>\n {children}\n\n {posterProp && (\n <Poster\n src={isString(posterProp) ? posterProp : undefined}\n render={isRenderProp(posterProp) ? posterProp : undefined}\n className={poster(false)}\n />\n )}\n\n <BufferingIndicator\n render={(props) => (\n <div {...props} className={bufferingIndicator}>\n <SpinnerIcon className={icon} />\n </div>\n )}\n />\n\n <ErrorDialog classes={errorClasses} />\n\n <Controls.Root\n data-controls=\"\" // Used as a hook for Tailwind has-[] styles\n className={controls}\n >\n <Tooltip.Provider>\n <div className={buttonGroup}>\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <PlayButton\n render={(props) => (\n <Button variant=\"icon\" {...props} className={iconState.play.button}>\n <RestartIcon className={cn(icon, iconState.play.restart)} />\n <PlayIcon className={cn(icon, iconState.play.play)} />\n <PauseIcon className={cn(icon, iconState.play.pause)} />\n </Button>\n )}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <PlayLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <SeekButton\n seconds={-SEEK_TIME}\n render={(props) => (\n <Button variant=\"icon\" {...props} className={seek.button}>\n <span className={iconContainer}>\n <SeekIcon className={cn(icon, iconFlipped)} />\n <span className={cn(seek.label, seek.labelBackward)}>{SEEK_TIME}</span>\n </span>\n </Button>\n )}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>Seek backward {SEEK_TIME} seconds</Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <SeekButton\n seconds={SEEK_TIME}\n render={(props) => (\n <Button variant=\"icon\" {...props} className={seek.button}>\n <span className={iconContainer}>\n <SeekIcon className={icon} />\n <span className={cn(seek.label, seek.labelForward)}>{SEEK_TIME}</span>\n </span>\n </Button>\n )}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>Seek forward {SEEK_TIME} seconds</Tooltip.Popup>\n </Tooltip.Root>\n </div>\n\n <div className={time.controls}>\n <Time.Group className={time.group}>\n <Time.Value type=\"current\" className={time.current} />\n <Time.Separator className={time.separator} />\n <Time.Value type=\"duration\" className={time.duration} />\n </Time.Group>\n\n <TimeSlider.Root render={(props) => <SliderRoot {...props} />}>\n <TimeSlider.Track render={(props) => <SliderTrack {...props} />}>\n <TimeSlider.Fill render={(props) => <SliderFill {...props} />} />\n <TimeSlider.Buffer render={(props) => <SliderFill type=\"buffer\" {...props} />} />\n </TimeSlider.Track>\n <TimeSlider.Thumb render={(props) => <SliderThumb {...props} />} />\n <div className={preview.root}>\n <div className={preview.thumbnailWrapper}>\n <Slider.Thumbnail className={preview.thumbnail} />\n </div>\n <TimeSlider.Value type=\"pointer\" className={preview.timestamp} />\n <SpinnerIcon className={cn(icon, preview.spinner)} />\n </div>\n </TimeSlider.Root>\n </div>\n\n <div className={buttonGroup}>\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <PlaybackRateButton\n render={(props) => <Button variant=\"icon\" {...props} className={playbackRate.button} />}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>Toggle playback rate</Tooltip.Popup>\n </Tooltip.Root>\n\n <VolumePopover />\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <CaptionsButton\n render={(props) => (\n <Button variant=\"icon\" {...props} className={iconState.captions.button}>\n <CaptionsOffIcon className={cn(icon, iconState.captions.off)} />\n <CaptionsOnIcon className={cn(icon, iconState.captions.on)} />\n </Button>\n )}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <CaptionsLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <PiPButton\n render={(props) => (\n <Button variant=\"icon\" {...props} className={iconState.pip.button}>\n <PipEnterIcon className={cn(icon, iconState.pip.off)} />\n <PipExitIcon className={cn(icon, iconState.pip.on)} />\n </Button>\n )}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <PiPLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <FullscreenButton\n render={(props) => (\n <Button variant=\"icon\" {...props} className={iconState.fullscreen.button}>\n <FullscreenEnterIcon className={cn(icon, iconState.fullscreen.enter)} />\n <FullscreenExitIcon className={cn(icon, iconState.fullscreen.exit)} />\n </Button>\n )}\n />\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <FullscreenLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n </div>\n </Tooltip.Provider>\n </Controls.Root>\n\n <div className={overlay} />\n </Container>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"minimal-skin.tailwind.js","names":["Popover.Root","Popover.Trigger","Popover.Popup","VolumeSlider.Root","VolumeSlider.Track","VolumeSlider.Fill","VolumeSlider.Thumb","Controls.Root","Tooltip.Provider","Tooltip.Root","Tooltip.Trigger","Tooltip.Popup","Time.Group","Time.Value","Time.Separator","TimeSlider.Root","TimeSlider.Track","TimeSlider.Fill","TimeSlider.Buffer","TimeSlider.Thumb","Slider.Thumbnail","TimeSlider.Value"],"sources":["../../../../src/presets/video/minimal-skin.tailwind.tsx"],"sourcesContent":["import {\n CaptionsOffIcon,\n CaptionsOnIcon,\n FullscreenEnterIcon,\n FullscreenExitIcon,\n PauseIcon,\n PipEnterIcon,\n PipExitIcon,\n PlayIcon,\n RestartIcon,\n SeekIcon,\n SpinnerIcon,\n VolumeHighIcon,\n VolumeLowIcon,\n VolumeOffIcon,\n} from '@videojs/icons/react/minimal';\nimport { playbackRate } from '@videojs/skins/default/tailwind/video.tailwind';\nimport {\n bufferingIndicator,\n button,\n buttonGroup,\n controls,\n error,\n icon,\n iconContainer,\n iconFlipped,\n iconState,\n overlay,\n popup,\n poster,\n preview,\n root,\n seek,\n slider,\n time,\n} from '@videojs/skins/minimal/tailwind/video.tailwind';\nimport { isString } from '@videojs/utils/predicate';\nimport { cn } from '@videojs/utils/style';\nimport { type ComponentProps, forwardRef, type ReactNode } from 'react';\nimport { Container, usePlayer } from '@/player/context';\nimport { BufferingIndicator } from '@/ui/buffering-indicator';\nimport { CaptionsButton } from '@/ui/captions-button';\nimport { Controls } from '@/ui/controls';\nimport { FullscreenButton } from '@/ui/fullscreen-button';\nimport { MuteButton } from '@/ui/mute-button';\nimport { PiPButton } from '@/ui/pip-button';\nimport { PlayButton } from '@/ui/play-button';\nimport { PlaybackRateButton } from '@/ui/playback-rate-button';\nimport { Popover } from '@/ui/popover';\nimport { Poster } from '@/ui/poster';\nimport { SeekButton } from '@/ui/seek-button';\nimport { Slider } from '@/ui/slider';\nimport { Time } from '@/ui/time';\nimport { TimeSlider } from '@/ui/time-slider';\nimport { Tooltip } from '@/ui/tooltip';\nimport { VolumeSlider } from '@/ui/volume-slider';\nimport { isRenderProp } from '@/utils/use-render';\nimport { ErrorDialog } from '../error-dialog';\nimport type { MinimalVideoSkinProps } from './minimal-skin';\n\nconst SEEK_TIME = 10;\n\nconst ERROR_CLASSNAMES = {\n root: error.root,\n dialog: error.dialog,\n content: error.content,\n title: error.title,\n description: error.description,\n actions: error.actions,\n close: cn(button.base, button.primary),\n};\n\n/* --------------------------------------- Components ---------------------------------------- */\n\nconst Button = forwardRef<HTMLButtonElement, ComponentProps<'button'>>(function Button({ className, ...props }, ref) {\n return (\n <button ref={ref} type=\"button\" className={cn(button.base, button.subtle, button.icon, className)} {...props} />\n );\n});\n\nconst SliderRoot = forwardRef<HTMLDivElement, ComponentProps<'div'>>(function SliderRoot({ className, ...props }, ref) {\n return <div ref={ref} className={cn(slider.root, className)} {...props} />;\n});\n\nconst SliderTrack = forwardRef<HTMLDivElement, ComponentProps<'div'>>(function SliderTrack(\n { className, ...props },\n ref\n) {\n return <div ref={ref} className={cn(slider.track, className)} {...props} />;\n});\n\nconst SliderFill = forwardRef<HTMLDivElement, ComponentProps<'div'> & { type?: 'fill' | 'buffer' }>(function SliderFill(\n { type = 'fill', className, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n className={cn(slider.fill.base, type === 'fill' ? slider.fill.fill : slider.fill.buffer, className)}\n {...props}\n />\n );\n});\n\nconst SliderBuffer = forwardRef<HTMLDivElement, ComponentProps<'div'>>(function SliderBuffer(props, ref) {\n return <SliderFill type=\"buffer\" ref={ref} {...props} />;\n});\n\nconst SliderThumb = forwardRef<HTMLDivElement, ComponentProps<'div'> & { persistent?: boolean }>(function SliderThumb(\n { persistent, className, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n className={cn(slider.thumb.base, persistent ? undefined : slider.thumb.interactive, className)}\n {...props}\n />\n );\n});\n\nfunction PlayLabel(): string {\n const paused = usePlayer((s) => Boolean(s.paused));\n const ended = usePlayer((s) => Boolean(s.ended));\n if (ended) return 'Replay';\n return paused ? 'Play' : 'Pause';\n}\n\nfunction CaptionsLabel(): string {\n const active = usePlayer((s) => Boolean(s.subtitlesShowing));\n return active ? 'Disable captions' : 'Enable captions';\n}\n\nfunction PiPLabel(): string {\n const pip = usePlayer((s) => Boolean(s.pip));\n return pip ? 'Exit picture-in-picture' : 'Enter picture-in-picture';\n}\n\nfunction FullscreenLabel(): string {\n const fullscreen = usePlayer((s) => Boolean(s.fullscreen));\n return fullscreen ? 'Exit fullscreen' : 'Enter fullscreen';\n}\n\nfunction VolumePopover(): ReactNode {\n const volumeUnsupported = usePlayer((s) => s.volumeAvailability === 'unsupported');\n\n const muteButton = (\n <MuteButton className={iconState.mute.button} render={<Button />}>\n <VolumeOffIcon className={cn(icon, iconState.mute.volumeOff)} />\n <VolumeLowIcon className={cn(icon, iconState.mute.volumeLow)} />\n <VolumeHighIcon className={cn(icon, iconState.mute.volumeHigh)} />\n </MuteButton>\n );\n\n if (volumeUnsupported) return muteButton;\n\n return (\n <Popover.Root openOnHover delay={200} closeDelay={100} side=\"top\">\n <Popover.Trigger render={muteButton} />\n <Popover.Popup className={cn(popup.volume)}>\n <VolumeSlider.Root orientation=\"vertical\" thumbAlignment=\"edge\" render={<SliderRoot />}>\n <VolumeSlider.Track render={<SliderTrack />}>\n <VolumeSlider.Fill render={<SliderFill />} />\n </VolumeSlider.Track>\n <VolumeSlider.Thumb render={(props) => <SliderThumb persistent {...props} />} />\n </VolumeSlider.Root>\n </Popover.Popup>\n </Popover.Root>\n );\n}\n\n/* ------------------------------------------ Skin ------------------------------------------- */\n\nexport function MinimalVideoSkinTailwind(props: MinimalVideoSkinProps): ReactNode {\n const { children, className, poster: posterProp, ...rest } = props;\n\n return (\n <Container className={cn(root(false), className)} {...rest}>\n {children}\n\n {posterProp && (\n <Poster\n src={isString(posterProp) ? posterProp : undefined}\n render={isRenderProp(posterProp) ? posterProp : undefined}\n className={poster(false)}\n />\n )}\n\n <BufferingIndicator\n render={(props) => (\n <div {...props} className={bufferingIndicator}>\n <SpinnerIcon className={icon} />\n </div>\n )}\n />\n\n <ErrorDialog classNames={ERROR_CLASSNAMES} />\n\n <Controls.Root\n data-controls=\"\" // Used as a hook for Tailwind has-[] styles\n className={controls}\n >\n <Tooltip.Provider>\n <div className={buttonGroup}>\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <PlayButton className={iconState.play.button} render={<Button />}>\n <RestartIcon className={cn(icon, iconState.play.restart)} />\n <PlayIcon className={cn(icon, iconState.play.play)} />\n <PauseIcon className={cn(icon, iconState.play.pause)} />\n </PlayButton>\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <PlayLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <SeekButton seconds={-SEEK_TIME} className={seek.button} render={<Button />}>\n <span className={iconContainer}>\n <SeekIcon className={cn(icon, iconFlipped)} />\n <span className={cn(seek.label, seek.labelBackward)}>{SEEK_TIME}</span>\n </span>\n </SeekButton>\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>Seek backward {SEEK_TIME} seconds</Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <SeekButton seconds={SEEK_TIME} className={seek.button} render={<Button />}>\n <span className={iconContainer}>\n <SeekIcon className={icon} />\n <span className={cn(seek.label, seek.labelForward)}>{SEEK_TIME}</span>\n </span>\n </SeekButton>\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>Seek forward {SEEK_TIME} seconds</Tooltip.Popup>\n </Tooltip.Root>\n </div>\n\n <div className={time.controls}>\n <Time.Group className={time.group}>\n <Time.Value type=\"current\" className={time.current} />\n <Time.Separator className={time.separator} />\n <Time.Value type=\"duration\" className={time.duration} />\n </Time.Group>\n\n <TimeSlider.Root render={<SliderRoot />}>\n <TimeSlider.Track render={<SliderTrack />}>\n <TimeSlider.Fill render={<SliderFill />} />\n <TimeSlider.Buffer render={<SliderBuffer />} />\n </TimeSlider.Track>\n <TimeSlider.Thumb render={<SliderThumb />} />\n <div className={preview.root}>\n <div className={preview.thumbnailWrapper}>\n <Slider.Thumbnail className={preview.thumbnail} />\n </div>\n <TimeSlider.Value type=\"pointer\" className={preview.timestamp} />\n <SpinnerIcon className={cn(icon, preview.spinner)} />\n </div>\n </TimeSlider.Root>\n </div>\n\n <div className={buttonGroup}>\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger render={<PlaybackRateButton className={playbackRate.button} render={<Button />} />} />\n <Tooltip.Popup className={cn(popup.tooltip)}>Toggle playback rate</Tooltip.Popup>\n </Tooltip.Root>\n\n <VolumePopover />\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <CaptionsButton className={iconState.captions.button} render={<Button />}>\n <CaptionsOffIcon className={cn(icon, iconState.captions.off)} />\n <CaptionsOnIcon className={cn(icon, iconState.captions.on)} />\n </CaptionsButton>\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <CaptionsLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <PiPButton className={iconState.pip.button} render={<Button />}>\n <PipEnterIcon className={cn(icon, iconState.pip.off)} />\n <PipExitIcon className={cn(icon, iconState.pip.on)} />\n </PiPButton>\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <PiPLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n\n <Tooltip.Root side=\"top\">\n <Tooltip.Trigger\n render={\n <FullscreenButton className={iconState.fullscreen.button} render={<Button />}>\n <FullscreenEnterIcon className={cn(icon, iconState.fullscreen.enter)} />\n <FullscreenExitIcon className={cn(icon, iconState.fullscreen.exit)} />\n </FullscreenButton>\n }\n />\n <Tooltip.Popup className={cn(popup.tooltip)}>\n <FullscreenLabel />\n </Tooltip.Popup>\n </Tooltip.Root>\n </div>\n </Tooltip.Provider>\n </Controls.Root>\n\n <div className={overlay} />\n </Container>\n );\n}\n"],"mappings":"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"}
@@ -1,103 +1,3 @@
1
- /* ==========================================================================
2
- Icon State Visibility for Video Skins
3
-
4
- Data-attribute-driven visibility rules for multi-state icon buttons.
5
- Uses :is() with both element selectors (for HTML custom element wrappers)
6
- and class selectors (for React rendered SVG elements).
7
- ========================================================================== */
8
-
9
- /* --- All icons hidden by default --- */
10
-
11
- .media-button--play .media-icon--restart,
12
- .media-button--play .media-icon--play,
13
- .media-button--play .media-icon--pause,
14
- .media-button--mute .media-icon--volume-off,
15
- .media-button--mute .media-icon--volume-low,
16
- .media-button--mute .media-icon--volume-high,
17
- .media-button--fullscreen .media-icon--fullscreen-enter,
18
- .media-button--fullscreen .media-icon--fullscreen-exit,
19
- .media-button--pip .media-icon--pip-enter,
20
- .media-button--pip .media-icon--pip-exit,
21
- .media-button--captions .media-icon--captions-off,
22
- .media-button--captions .media-icon--captions-on {
23
- display: none;
24
- opacity: 0;
25
- }
26
-
27
- /* --- Active icon per state --- */
28
-
29
- /* Play: ended → restart */
30
- .media-button--play[data-ended] .media-icon--restart,
31
- /* Play: paused (not ended) → play */
32
- .media-button--play:not([data-ended])[data-paused] .media-icon--play,
33
- /* Play: playing (not paused, not ended) → pause */
34
- .media-button--play:not([data-paused]):not([data-ended]) .media-icon--pause,
35
- /* Mute: muted → volume off */
36
- .media-button--mute[data-muted] .media-icon--volume-off,
37
- /* Mute: volume low (not muted) → volume low */
38
- .media-button--mute:not([data-muted])[data-volume-level="low"] .media-icon--volume-low,
39
- /* Mute: volume high (not muted, not low) → volume high */
40
- .media-button--mute:not([data-muted]):not([data-volume-level="low"]) .media-icon--volume-high,
41
- /* Fullscreen: not fullscreen → enter */
42
- .media-button--fullscreen:not([data-fullscreen]) .media-icon--fullscreen-enter,
43
- /* Fullscreen: fullscreen → exit */
44
- .media-button--fullscreen[data-fullscreen] .media-icon--fullscreen-exit,
45
- /* Picture-in-Picture: not active → enter */
46
- .media-button--pip:not([data-pip]) .media-icon--pip-enter,
47
- /* Picture-in-Picture: active → exit */
48
- .media-button--pip[data-pip] .media-icon--pip-exit,
49
- /* Captions: not active → captions off */
50
- .media-button--captions:not([data-active]) .media-icon--captions-off,
51
- /* Captions: active → captions on */
52
- .media-button--captions[data-active] .media-icon--captions-on {
53
- display: block;
54
- opacity: 1;
55
- }
56
-
57
- /* ==========================================================================
58
- Tooltip Label State Visibility for Video Skins
59
-
60
- Data-attribute-driven visibility rules for multi-state tooltip labels.
61
- Uses adjacent sibling selectors to match button state → tooltip content.
62
- ========================================================================== */
63
-
64
- /* --- All multi-state labels hidden by default --- */
65
-
66
- .media-tooltip-label {
67
- display: none;
68
- }
69
-
70
- /* --- Active label per state --- */
71
-
72
- /* Play: ended → replay */
73
- .media-button--play[data-ended] + .media-tooltip .media-tooltip-label--replay,
74
- /* Play: paused (not ended) → play */
75
- .media-button--play:not([data-ended])[data-paused] + .media-tooltip
76
- .media-tooltip-label--play,
77
- /* Play: playing (not paused, not ended) → pause */
78
- .media-button--play:not([data-paused]):not([data-ended]) + .media-tooltip
79
- .media-tooltip-label--pause,
80
- /* Fullscreen: not fullscreen → enter */
81
- .media-button--fullscreen:not([data-fullscreen]) + .media-tooltip
82
- .media-tooltip-label--enter-fullscreen,
83
- /* Fullscreen: fullscreen → exit */
84
- .media-button--fullscreen[data-fullscreen] + .media-tooltip
85
- .media-tooltip-label--exit-fullscreen,
86
- /* Captions: not active → enable */
87
- .media-button--captions:not([data-active]) + .media-tooltip
88
- .media-tooltip-label--enable-captions,
89
- /* Captions: active → disable */
90
- .media-button--captions[data-active] + .media-tooltip
91
- .media-tooltip-label--disable-captions,
92
- /* PiP: not in pip → enter */
93
- .media-button--pip:not([data-pip]) + .media-tooltip
94
- .media-tooltip-label--enter-pip,
95
- /* PiP: in pip → exit */
96
- .media-button--pip[data-pip] + .media-tooltip
97
- .media-tooltip-label--exit-pip {
98
- display: block;
99
- }
100
-
101
1
  /* ==========================================================================
102
2
  Reset
103
3
  ========================================================================== */
@@ -215,27 +115,20 @@
215
115
  backdrop-filter: blur(0) saturate(1.5);
216
116
  opacity: 0;
217
117
  pointer-events: none;
118
+ transition-property: opacity, backdrop-filter;
119
+ transition-duration: var(--media-controls-transition-duration);
120
+ transition-delay: var(--media-controls-transition-delay);
121
+ transition-timing-function: ease-out;
122
+ }
218
123
 
219
- @media (pointer: fine) {
220
- transition-property: opacity, backdrop-filter;
221
- transition-duration: 300ms;
222
- transition-delay: 500ms;
223
- transition-timing-function: ease-out;
224
-
225
- @media (prefers-reduced-motion: reduce) {
226
- transition-duration: 100ms;
227
- }
228
- }
124
+ .media-default-skin .media-error ~ .media-overlay {
125
+ transition-duration: var(--media-error-dialog-transition-duration);
126
+ transition-delay: var(--media-error-dialog-transition-delay);
229
127
  }
230
128
 
231
129
  .media-default-skin .media-controls[data-visible] ~ .media-overlay,
232
130
  .media-default-skin .media-error[data-open] ~ .media-overlay {
233
131
  opacity: 1;
234
-
235
- @media (pointer: fine) {
236
- transition-duration: 150ms;
237
- transition-delay: 0ms;
238
- }
239
132
  }
240
133
 
241
134
  .media-default-skin .media-error[data-open] ~ .media-overlay {
@@ -270,57 +163,7 @@
270
163
  ========================================================================== */
271
164
 
272
165
  .media-default-skin .media-error {
273
- position: absolute;
274
- inset: 0;
275
- z-index: 20;
276
- display: flex;
277
- align-items: center;
278
- justify-content: center;
279
- }
280
-
281
- .media-default-skin .media-error__dialog {
282
- display: flex;
283
- flex-direction: column;
284
- gap: 0.75rem;
285
- max-width: 18rem;
286
- padding: 0.75rem;
287
- border-radius: 1.75rem;
288
- color: oklch(1 0 0);
289
- font-size: 0.875rem;
290
- transition-property: opacity, scale;
291
- transition-duration: 500ms;
292
- transition-delay: 100ms;
293
- transition-timing-function: linear(
294
- 0,
295
- 0.034 1.5%,
296
- 0.763 9.7%,
297
- 1.066 13.9%,
298
- 1.198 19.9%,
299
- 1.184 21.8%,
300
- 0.963 37.5%,
301
- 0.997 50.9%,
302
- 1
303
- );
304
-
305
- /* Simple, fast transition for reduced motion users */
306
- @media (prefers-reduced-motion: reduce) {
307
- transition-duration: 100ms;
308
- transition-delay: 0ms;
309
- transition-timing-function: ease-out;
310
- }
311
- }
312
-
313
- .media-default-skin .media-error[data-starting-style] .media-error__dialog,
314
- .media-default-skin .media-error[data-ending-style] .media-error__dialog {
315
- opacity: 0;
316
- scale: 0.5;
317
- }
318
-
319
- .media-default-skin .media-error__content {
320
- display: flex;
321
- flex-direction: column;
322
- gap: 0.5rem;
323
- padding: 0.5rem 0.5rem 0.375rem;
166
+ outline: none;
324
167
  }
325
168
 
326
169
  .media-default-skin .media-error__title {
@@ -342,6 +185,10 @@
342
185
  }
343
186
  }
344
187
 
188
+ .media-default-skin .media-error[data-open] ~ .media-controls * {
189
+ visibility: hidden;
190
+ }
191
+
345
192
  /* ==========================================================================
346
193
  Controls
347
194
  ========================================================================== */
@@ -402,15 +249,11 @@
402
249
  justify-content: center;
403
250
  flex-shrink: 0;
404
251
  padding: 0.5rem 1rem;
405
- background: oklch(1 0 0);
406
252
  border: none;
407
253
  border-radius: calc(infinity * 1px);
408
254
  outline: 2px solid transparent;
409
255
  outline-offset: -2px;
410
- color: oklch(0 0 0);
411
- font-weight: 500;
412
- text-align: center;
413
- transition-property: background-color, color, outline-offset, scale;
256
+ transition-property: background-color, outline-offset, scale;
414
257
  transition-duration: 150ms;
415
258
  transition-timing-function: ease-out;
416
259
  cursor: pointer;
@@ -418,10 +261,14 @@
418
261
  touch-action: manipulation;
419
262
 
420
263
  &:focus-visible {
421
- outline-color: oklch(62.3% 0.214 259.815);
264
+ outline-color: currentColor;
422
265
  outline-offset: 2px;
423
266
  }
424
267
 
268
+ &:active {
269
+ scale: 0.98;
270
+ }
271
+
425
272
  &[disabled] {
426
273
  opacity: 0.5;
427
274
  filter: grayscale(1);
@@ -433,12 +280,16 @@
433
280
  }
434
281
  }
435
282
 
436
- /* Icon button variant */
437
- .media-default-skin .media-button--icon {
438
- display: grid;
439
- width: 2.125rem;
440
- padding: 0;
441
- aspect-ratio: 1;
283
+ /* Primary button variant */
284
+ .media-default-skin .media-button--primary {
285
+ background: oklch(1 0 0);
286
+ color: oklch(0 0 0);
287
+ font-weight: 500;
288
+ text-align: center;
289
+ }
290
+
291
+ /* Subtle button variant */
292
+ .media-default-skin .media-button--subtle {
442
293
  background: transparent;
443
294
  color: inherit;
444
295
  text-shadow: inherit;
@@ -449,6 +300,14 @@
449
300
  background-color: oklch(from currentColor l c h / 0.1);
450
301
  text-decoration: none;
451
302
  }
303
+ }
304
+
305
+ /* Icon button variant */
306
+ .media-default-skin .media-button--icon {
307
+ display: grid;
308
+ width: 2.125rem;
309
+ padding: 0;
310
+ aspect-ratio: 1;
452
311
 
453
312
  &:active {
454
313
  scale: 0.9;
@@ -465,7 +324,7 @@
465
324
  position: absolute;
466
325
  right: -1px;
467
326
  bottom: -3px;
468
- font-size: 0.75em;
327
+ font-size: 10px;
469
328
  font-weight: 480;
470
329
  font-variant-numeric: tabular-nums;
471
330
  }
@@ -688,6 +547,22 @@
688
547
  outline-color: oklch(from currentColor l c h / 0.25);
689
548
  outline-offset: 0;
690
549
  }
550
+
551
+ &::after {
552
+ content: "";
553
+ position: absolute;
554
+ inset: -4px;
555
+ border-radius: inherit;
556
+ box-shadow: 0 0 0 2px oklch(1 0 0);
557
+ transition-property: opacity, scale;
558
+ transition-duration: 150ms;
559
+ transition-timing-function: ease-out;
560
+ }
561
+
562
+ &:not(:focus-visible)::after {
563
+ scale: 0.5;
564
+ opacity: 0;
565
+ }
691
566
  }
692
567
 
693
568
  .media-default-skin .media-slider:active .media-slider__thumb,
@@ -763,7 +638,8 @@
763
638
  color: inherit;
764
639
  overflow: visible;
765
640
  transition-property: scale, opacity, filter;
766
- transition-duration: 150ms;
641
+ transition-duration: var(--media-popup-transition-duration);
642
+ transition-timing-function: var(--media-popup-transition-timing-function);
767
643
 
768
644
  &[data-starting-style],
769
645
  &[data-ending-style] {
@@ -882,6 +758,106 @@
882
758
  font-family: inherit;
883
759
  }
884
760
 
761
+ /* ==========================================================================
762
+ Icon State Visibility for Video Skins
763
+
764
+ Data-attribute-driven visibility rules for multi-state icon buttons.
765
+ Uses :is() with both element selectors (for HTML custom element wrappers)
766
+ and class selectors (for React rendered SVG elements).
767
+ ========================================================================== */
768
+
769
+ /* --- All icons hidden by default --- */
770
+
771
+ .media-button--play .media-icon--restart,
772
+ .media-button--play .media-icon--play,
773
+ .media-button--play .media-icon--pause,
774
+ .media-button--mute .media-icon--volume-off,
775
+ .media-button--mute .media-icon--volume-low,
776
+ .media-button--mute .media-icon--volume-high,
777
+ .media-button--fullscreen .media-icon--fullscreen-enter,
778
+ .media-button--fullscreen .media-icon--fullscreen-exit,
779
+ .media-button--pip .media-icon--pip-enter,
780
+ .media-button--pip .media-icon--pip-exit,
781
+ .media-button--captions .media-icon--captions-off,
782
+ .media-button--captions .media-icon--captions-on {
783
+ display: none;
784
+ opacity: 0;
785
+ }
786
+
787
+ /* --- Active icon per state --- */
788
+
789
+ /* Play: ended → restart */
790
+ .media-button--play[data-ended] .media-icon--restart,
791
+ /* Play: paused (not ended) → play */
792
+ .media-button--play:not([data-ended])[data-paused] .media-icon--play,
793
+ /* Play: playing (not paused, not ended) → pause */
794
+ .media-button--play:not([data-paused]):not([data-ended]) .media-icon--pause,
795
+ /* Mute: muted → volume off */
796
+ .media-button--mute[data-muted] .media-icon--volume-off,
797
+ /* Mute: volume low (not muted) → volume low */
798
+ .media-button--mute:not([data-muted])[data-volume-level="low"] .media-icon--volume-low,
799
+ /* Mute: volume high (not muted, not low) → volume high */
800
+ .media-button--mute:not([data-muted]):not([data-volume-level="low"]) .media-icon--volume-high,
801
+ /* Fullscreen: not fullscreen → enter */
802
+ .media-button--fullscreen:not([data-fullscreen]) .media-icon--fullscreen-enter,
803
+ /* Fullscreen: fullscreen → exit */
804
+ .media-button--fullscreen[data-fullscreen] .media-icon--fullscreen-exit,
805
+ /* Picture-in-Picture: not active → enter */
806
+ .media-button--pip:not([data-pip]) .media-icon--pip-enter,
807
+ /* Picture-in-Picture: active → exit */
808
+ .media-button--pip[data-pip] .media-icon--pip-exit,
809
+ /* Captions: not active → captions off */
810
+ .media-button--captions:not([data-active]) .media-icon--captions-off,
811
+ /* Captions: active → captions on */
812
+ .media-button--captions[data-active] .media-icon--captions-on {
813
+ display: block;
814
+ opacity: 1;
815
+ }
816
+
817
+ /* ==========================================================================
818
+ Tooltip Label State Visibility for Video Skins
819
+
820
+ Data-attribute-driven visibility rules for multi-state tooltip labels.
821
+ Uses adjacent sibling selectors to match button state → tooltip content.
822
+ ========================================================================== */
823
+
824
+ /* --- All multi-state labels hidden by default --- */
825
+
826
+ .media-tooltip-label {
827
+ display: none;
828
+ }
829
+
830
+ /* --- Active label per state --- */
831
+
832
+ /* Play: ended → replay */
833
+ .media-button--play[data-ended] + .media-tooltip .media-tooltip-label--replay,
834
+ /* Play: paused (not ended) → play */
835
+ .media-button--play:not([data-ended])[data-paused] + .media-tooltip
836
+ .media-tooltip-label--play,
837
+ /* Play: playing (not paused, not ended) → pause */
838
+ .media-button--play:not([data-paused]):not([data-ended]) + .media-tooltip
839
+ .media-tooltip-label--pause,
840
+ /* Fullscreen: not fullscreen → enter */
841
+ .media-button--fullscreen:not([data-fullscreen]) + .media-tooltip
842
+ .media-tooltip-label--enter-fullscreen,
843
+ /* Fullscreen: fullscreen → exit */
844
+ .media-button--fullscreen[data-fullscreen] + .media-tooltip
845
+ .media-tooltip-label--exit-fullscreen,
846
+ /* Captions: not active → enable */
847
+ .media-button--captions:not([data-active]) + .media-tooltip
848
+ .media-tooltip-label--enable-captions,
849
+ /* Captions: active → disable */
850
+ .media-button--captions[data-active] + .media-tooltip
851
+ .media-tooltip-label--disable-captions,
852
+ /* PiP: not in pip → enter */
853
+ .media-button--pip:not([data-pip]) + .media-tooltip
854
+ .media-tooltip-label--enter-pip,
855
+ /* PiP: in pip → exit */
856
+ .media-button--pip[data-pip] + .media-tooltip
857
+ .media-tooltip-label--exit-pip {
858
+ display: block;
859
+ }
860
+
885
861
 
886
862
  /* ==========================================================================
887
863
  Root
@@ -889,6 +865,17 @@
889
865
 
890
866
  .media-default-skin--video {
891
867
  background: oklch(0 0 0);
868
+ --media-spring-transition: linear(
869
+ 0,
870
+ 0.034 1.5%,
871
+ 0.763 9.7%,
872
+ 1.066 13.9%,
873
+ 1.198 19.9%,
874
+ 1.184 21.8%,
875
+ 0.963 37.5%,
876
+ 0.997 50.9%,
877
+ 1
878
+ );
892
879
  --media-border-color: oklch(0 0 0 / 0.1);
893
880
  --media-surface-background-color: oklch(1 0 0 / 0.1);
894
881
  --media-surface-inner-border-color: oklch(1 0 0 / 0.05);
@@ -898,6 +885,19 @@
898
885
  --media-video-border-radius: var(--media-border-radius, 2rem);
899
886
  --media-controls-transition-duration: 100ms;
900
887
  --media-controls-transition-delay: 0ms;
888
+ --media-controls-transition-timing-function: ease-out;
889
+ --media-error-dialog-transition-duration: 350ms;
890
+ --media-error-dialog-transition-delay: 100ms;
891
+ --media-error-dialog-transition-timing-function: var(--media-spring-transition);
892
+ --media-popup-transition-duration: 100ms;
893
+ --media-popup-transition-timing-function: ease-out;
894
+
895
+ @media (prefers-reduced-motion: reduce) {
896
+ --media-error-dialog-transition-duration: 50ms;
897
+ --media-error-dialog-transition-delay: 0ms;
898
+ --media-error-dialog-transition-timing-function: ease-out;
899
+ --media-popup-transition-duration: 0ms;
900
+ }
901
901
 
902
902
  @media (prefers-color-scheme: dark) {
903
903
  --media-border-color: oklch(1 0 0 / 0.15);
@@ -913,7 +913,7 @@
913
913
  --media-controls-transition-duration: 150ms;
914
914
  }
915
915
  @media (prefers-reduced-motion: reduce) {
916
- --media-controls-transition-duration: 100ms;
916
+ --media-controls-transition-duration: 50ms;
917
917
  }
918
918
  }
919
919
 
@@ -933,6 +933,55 @@
933
933
  }
934
934
  }
935
935
 
936
+ /* ==========================================================================
937
+ Error Dialog
938
+ ========================================================================== */
939
+
940
+ .media-default-skin--video .media-error {
941
+ position: absolute;
942
+ inset: 0;
943
+ z-index: 20;
944
+ display: flex;
945
+ align-items: center;
946
+ justify-content: center;
947
+ }
948
+
949
+ .media-default-skin--video .media-error__dialog {
950
+ display: flex;
951
+ flex-direction: column;
952
+ gap: 0.75rem;
953
+ max-width: 18rem;
954
+ padding: 0.75rem;
955
+ border-radius: 1.75rem;
956
+ color: oklch(1 0 0);
957
+ text-shadow: 0 1px 0 oklch(0 0 0 / 0.25);
958
+ transition-property: opacity, scale;
959
+ transition-duration: var(--media-error-dialog-transition-duration);
960
+ transition-delay: var(--media-error-dialog-transition-delay);
961
+ transition-timing-function: var(--media-error-dialog-transition-timing-function);
962
+ }
963
+
964
+ .media-default-skin--video .media-error[data-starting-style] .media-error__dialog,
965
+ .media-default-skin--video .media-error[data-ending-style] .media-error__dialog {
966
+ opacity: 0;
967
+ scale: 0.5;
968
+ }
969
+ .media-default-skin--video .media-error[data-ending-style] .media-error__dialog {
970
+ transition-delay: 0ms;
971
+ }
972
+
973
+ .media-default-skin--video .media-error__content {
974
+ display: flex;
975
+ flex-direction: column;
976
+ gap: 0.5rem;
977
+ padding: 0.5rem 0.5rem 0.375rem;
978
+ text-shadow: inherit;
979
+ }
980
+
981
+ .media-default-skin--video .media-error__title {
982
+ font-size: 1rem;
983
+ }
984
+
936
985
  /* ==========================================================================
937
986
  Controls (hide/show behavior)
938
987
  ========================================================================== */
@@ -943,9 +992,9 @@
943
992
  inset-inline: 0.75rem;
944
993
  z-index: 10;
945
994
  color: var(--media-color-primary, oklch(1 0 0));
946
- transition-timing-function: ease-out;
947
995
  transition-duration: var(--media-controls-transition-duration);
948
996
  transition-delay: var(--media-controls-transition-delay);
997
+ transition-timing-function: var(--media-controls-transition-timing-function);
949
998
  transform-origin: bottom;
950
999
 
951
1000
  @media (pointer: fine) {
@@ -963,12 +1012,8 @@
963
1012
  pointer-events: none;
964
1013
  scale: 0.9;
965
1014
 
966
- @media (pointer: fine) {
1015
+ @media (pointer: fine) and (prefers-reduced-motion: no-preference) {
967
1016
  filter: blur(8px);
968
-
969
- @media (prefers-reduced-motion: reduce) {
970
- filter: blur(0);
971
- }
972
1017
  }
973
1018
 
974
1019
  @media (prefers-reduced-motion: reduce) {
@@ -977,6 +1022,10 @@
977
1022
  }
978
1023
  }
979
1024
 
1025
+ .media-default-skin--video .media-error[data-open] ~ .media-controls {
1026
+ display: none;
1027
+ }
1028
+
980
1029
  /* Hide cursor when controls are hidden in fullscreen */
981
1030
  @media (pointer: fine) {
982
1031
  .media-default-skin--video:fullscreen:has(.media-controls:not([data-visible])) {
@@ -993,7 +1042,7 @@
993
1042
  box-shadow: 0 0 0 1px oklch(0 0 0 / 0.05);
994
1043
  }
995
1044
 
996
- .media-default-skin .media-slider__preview {
1045
+ .media-default-skin--video .media-slider__preview {
997
1046
  position: absolute;
998
1047
  left: var(--media-slider-pointer);
999
1048
  bottom: calc(100% + 1.2rem);
@@ -1015,7 +1064,7 @@
1015
1064
  max-height: 6rem;
1016
1065
  }
1017
1066
  }
1018
- .media-default-skin .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
1067
+ .media-default-skin--video .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
1019
1068
  opacity: 1;
1020
1069
  scale: 1;
1021
1070
  filter: blur(0);