@zuude-ui/video 0.1.4 → 0.1.6
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 +223 -0
- package/dist/index.cjs +1 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -90
- package/dist/index.d.ts +36 -90
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/index.cjs +2 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +51 -0
- package/dist/utils/index.d.ts +51 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +10 -5
package/README.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# @zuude-ui/video
|
|
2
|
+
|
|
3
|
+
A comprehensive video player library with advanced time formatting utilities.
|
|
4
|
+
|
|
5
|
+
## Video Time Formatting Utilities
|
|
6
|
+
|
|
7
|
+
Similar to `date-fns` but specifically designed for video durations and time formatting.
|
|
8
|
+
|
|
9
|
+
### Basic Usage
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { formatTime, humanizeTime, parseTime } from "@zuude-ui/video/utils";
|
|
13
|
+
|
|
14
|
+
// Basic formatting
|
|
15
|
+
formatTime(125.5); // "2:05"
|
|
16
|
+
formatTime(125.5, "h:mm:ss"); // "0:02:05"
|
|
17
|
+
formatTime(125.5, "ss"); // "125s"
|
|
18
|
+
|
|
19
|
+
// Human readable
|
|
20
|
+
humanizeTime(125.5); // "2 minutes 5 seconds"
|
|
21
|
+
humanizeTime(125.5, { compact: true }); // "2 minutes"
|
|
22
|
+
|
|
23
|
+
// Parse time strings
|
|
24
|
+
parseTime("2:30"); // 150
|
|
25
|
+
parseTime("1:23:45"); // 5025
|
|
26
|
+
parseTime("90s"); // 90
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Available Functions
|
|
30
|
+
|
|
31
|
+
#### `formatTime(time, options)`
|
|
32
|
+
|
|
33
|
+
Format time in seconds to various formats.
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
|
|
37
|
+
- `time` (number): Time in seconds
|
|
38
|
+
- `options` (TimeFormatOptions | TimeFormat): Format options
|
|
39
|
+
|
|
40
|
+
**Formats:**
|
|
41
|
+
|
|
42
|
+
- `"mm:ss"` (default): "2:05"
|
|
43
|
+
- `"h:mm:ss"`: "0:02:05"
|
|
44
|
+
- `"ss"`: "125s"
|
|
45
|
+
- `"human"`: "2 minutes 5 seconds"
|
|
46
|
+
- `"compact"`: "2:05"
|
|
47
|
+
- `"detailed"`: "00:02:05.000"
|
|
48
|
+
|
|
49
|
+
**Options:**
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
interface TimeFormatOptions {
|
|
53
|
+
format?: TimeFormat;
|
|
54
|
+
showHours?: boolean;
|
|
55
|
+
showLeadingZeros?: boolean;
|
|
56
|
+
showMilliseconds?: boolean;
|
|
57
|
+
humanize?: boolean;
|
|
58
|
+
compact?: boolean;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### `humanizeTime(time, options)`
|
|
63
|
+
|
|
64
|
+
Convert time to human-readable format.
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
humanizeTime(125.5); // "2 minutes 5 seconds"
|
|
68
|
+
humanizeTime(125.5, { compact: true }); // "2 minutes"
|
|
69
|
+
humanizeTime(3600); // "1 hour"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### `compactTime(time)`
|
|
73
|
+
|
|
74
|
+
Compact time format.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
compactTime(125.5); // "2:05"
|
|
78
|
+
compactTime(3600); // "1:00:00"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### `detailedTime(time, options)`
|
|
82
|
+
|
|
83
|
+
Detailed time format with optional milliseconds.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
detailedTime(125.5); // "00:02:05"
|
|
87
|
+
detailedTime(125.5, { showMilliseconds: true }); // "00:02:05.000"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### `parseTime(timeString)`
|
|
91
|
+
|
|
92
|
+
Parse time string to seconds.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
parseTime("2:30"); // 150
|
|
96
|
+
parseTime("1:23:45"); // 5025
|
|
97
|
+
parseTime("90s"); // 90
|
|
98
|
+
parseTime("1.5m"); // 90
|
|
99
|
+
parseTime("0.5h"); // 1800
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### `timeRemaining(current, total, format)`
|
|
103
|
+
|
|
104
|
+
Calculate remaining time.
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
timeRemaining(125.5, 3600); // "57:54"
|
|
108
|
+
timeRemaining(125.5, 3600, "human"); // "57 minutes 54 seconds"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### `formatTimeWithPercentage(current, total, format)`
|
|
112
|
+
|
|
113
|
+
Format time with percentage.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
formatTimeWithPercentage(125.5, 3600); // "2:05 (3%)"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### `getTimeSegments(duration, segments)`
|
|
120
|
+
|
|
121
|
+
Get time segments for timeline.
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
getTimeSegments(3600, 5); // [0, 720, 1440, 2160, 2880, 3600]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### `formatTimeForAccessibility(time)`
|
|
128
|
+
|
|
129
|
+
Format time for screen readers.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
formatTimeForAccessibility(125.5); // "2 minutes, 5 seconds"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Advanced Examples
|
|
136
|
+
|
|
137
|
+
#### Custom Timeline Component
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import { formatTime, getTimeSegments } from "@zuude-ui/video/utils";
|
|
141
|
+
|
|
142
|
+
const Timeline = ({ currentTime, duration }) => {
|
|
143
|
+
const segments = getTimeSegments(duration, 10);
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<div className="timeline">
|
|
147
|
+
{segments.map((time, i) => (
|
|
148
|
+
<div key={i} className="segment">
|
|
149
|
+
{formatTime(time, "mm:ss")}
|
|
150
|
+
</div>
|
|
151
|
+
))}
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Video Progress Display
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import {
|
|
161
|
+
formatTime,
|
|
162
|
+
timeRemaining,
|
|
163
|
+
formatTimeWithPercentage,
|
|
164
|
+
} from "@zuude-ui/video/utils";
|
|
165
|
+
|
|
166
|
+
const VideoProgress = ({ currentTime, duration }) => {
|
|
167
|
+
return (
|
|
168
|
+
<div className="video-progress">
|
|
169
|
+
<span>{formatTime(currentTime)}</span>
|
|
170
|
+
<span>{timeRemaining(currentTime, duration)}</span>
|
|
171
|
+
<span>{formatTimeWithPercentage(currentTime, duration)}</span>
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Accessibility-Friendly Time Display
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { formatTimeForAccessibility } from "@zuude-ui/video/utils";
|
|
181
|
+
|
|
182
|
+
const AccessibleTimeDisplay = ({ time }) => {
|
|
183
|
+
return (
|
|
184
|
+
<span aria-label={formatTimeForAccessibility(time)}>
|
|
185
|
+
{formatTime(time)}
|
|
186
|
+
</span>
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Comparison with Other Libraries
|
|
192
|
+
|
|
193
|
+
| Feature | @zuude-ui/video | date-fns | humanize-duration |
|
|
194
|
+
| ------------------ | --------------- | -------- | ----------------- |
|
|
195
|
+
| Video-specific | ✅ | ❌ | ❌ |
|
|
196
|
+
| Multiple formats | ✅ | ✅ | ❌ |
|
|
197
|
+
| Time parsing | ✅ | ❌ | ❌ |
|
|
198
|
+
| Accessibility | ✅ | ❌ | ❌ |
|
|
199
|
+
| Percentage display | ✅ | ❌ | ❌ |
|
|
200
|
+
| Time segments | ✅ | ❌ | ❌ |
|
|
201
|
+
| Bundle size | Small | Large | Medium |
|
|
202
|
+
|
|
203
|
+
### Installation
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npm install @zuude-ui/video
|
|
207
|
+
# or
|
|
208
|
+
yarn add @zuude-ui/video
|
|
209
|
+
# or
|
|
210
|
+
pnpm add @zuude-ui/video
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### TypeScript Support
|
|
214
|
+
|
|
215
|
+
Full TypeScript support with comprehensive type definitions:
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import type { TimeFormat, TimeFormatOptions } from "@zuude-ui/video/utils";
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Video Player Components
|
|
222
|
+
|
|
223
|
+
The library also includes a complete video player with hooks and components. See the main documentation for video player usage.
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var
|
|
2
|
-
`);var E=d(require("react"),1);var g=d(require("react"),1),$=require("react/jsx-runtime"),z=g.default.createContext(void 0),l=()=>{let e=g.default.useContext(z);if(!e)throw new Error("useVideo must be used within a VideoProvider");return e},q=({children:e,videoRef:n,duration:r,showHidingElement:t,setShowHidingElement:u})=>{let[s,o]=g.default.useState(!1);return(0,$.jsx)(z.Provider,{value:{videoRef:n,duration:r,isFullscreen:s,setIsFullscreen:o,showHidingElement:t,setShowHidingElement:u},children:e})};var B=d(require("react"),1),T=(e,n,r)=>{B.default.useEffect(()=>{if(!(e!=null&&e.current)||!n)return;(async()=>{var u;try{await((u=e.current)==null?void 0:u.play())}catch(s){if(s instanceof Error&&s.name==="NotAllowedError"){if(r==null||r("NotAllowedError"),console.error("NotAllowedError"),e!=null&&e.current){e.current.muted=!0;try{await e.current.play()}catch(o){console.error(o)}}}else console.error(s)}})()},[n,e==null?void 0:e.current])};var D=d(require("react"),1),w=(e,n)=>{D.default.useEffect(()=>{if(!(e!=null&&e.current)||!n)return;let r=e==null?void 0:e.current;r&&n&&(r.currentTime=n)},[n,e==null?void 0:e.current])};var U=d(require("react"),1),j=(e,n,r)=>{U.default.useEffect(()=>{if(!r||!(e!=null&&e.current))return;let t=new IntersectionObserver(u=>{u.forEach(s=>{var o;e!=null&&e.current&&(s.isIntersecting?e.current.play().catch(a=>{e.current&&(e.current.pause(),e.current.muted=!0,e.current.play(),console.error(a))}):(o=e.current)==null||o.pause())})},{threshold:n!=null?n:.5});return t.observe(e==null?void 0:e.current),()=>{t.disconnect()}},[r,e==null?void 0:e.current])};var L=d(require("react"),1),V=(e,n)=>{let[r,t]=L.default.useState(!1),u=L.default.useCallback(()=>{console.log(e==null?void 0:e.current),e!=null&&e.current&&(e.current.paused?e.current.play():e.current.pause())},[e==null?void 0:e.current]);return L.default.useEffect(()=>{if(!n||!(e!=null&&e.current))return;let s=()=>{t(!0)},o=()=>{t(!1)};if(t(!(e!=null&&e.current.paused)),e!=null&&e.current)return e.current.addEventListener("play",s),e.current.addEventListener("pause",o),()=>{var a,m;(a=e.current)==null||a.removeEventListener("play",s),(m=e.current)==null||m.removeEventListener("pause",o)}},[e==null?void 0:e.current,n]),{togglePlay:u,isPlaying:r}};var W=require("react/jsx-runtime"),G=()=>{let{videoRef:e}=l(),{togglePlay:n}=V(e,!0);return(0,W.jsx)("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},onClick:n})};var Y=d(require("react"),1);var F=d(require("react"),1),M=(e,n)=>{let[r,t]=F.default.useState(!1),u=F.default.useCallback(()=>{e!=null&&e.current&&(e.current.muted=!e.current.muted)},[e==null?void 0:e.current]);return F.default.useEffect(()=>{if(!n||!(e!=null&&e.current))return;t(e.current.muted);let s=()=>{e.current&&t(e.current.muted)};return e.current.addEventListener("volumechange",s),()=>{var o;(o=e.current)==null||o.removeEventListener("volumechange",s)}},[e==null?void 0:e.current,n]),{toggleMute:u,isMuted:r}};var J=d(require("react"),1);var S=()=>{let{videoRef:e,isFullscreen:n,setIsFullscreen:r}=l();J.default.useEffect(()=>{let u=()=>{r==null||r(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",u),()=>document.removeEventListener("fullscreenchange",u)},[]);let t=()=>{var a;let u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),s=e==null?void 0:e.current;if(s&&u){if(s.webkitEnterFullscreen){s.webkitEnterFullscreen();return}else if(s.requestFullscreen){s.requestFullscreen();return}}let o=(a=e==null?void 0:e.current)==null?void 0:a.closest("[data-zuude-video-wrapper]");o&&(n?document.exitFullscreen():o.requestFullscreen())};return{isFullscreen:n!=null?n:!1,toggleFullscreen:t}};var K=d(require("react"),1);var Q=()=>{let{videoRef:e,isPictureInPicture:n,setIsPictureInPicture:r}=l();K.default.useEffect(()=>{let u=()=>{r==null||r(!!document.pictureInPictureElement)};return document.addEventListener("pictureinpicturechange",u),()=>document.removeEventListener("pictureinpicturechange",u)},[]);let t=async()=>{let u=e==null?void 0:e.current;if(u)try{document.pictureInPictureElement?await document.exitPictureInPicture():await u.requestPictureInPicture()}catch(s){if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent))u.webkitEnterFullscreen?u.webkitEnterFullscreen():u.requestFullscreen&&u.requestFullscreen();else{let a=u.closest("[data-zuude-video-wrapper]");a&&(document.fullscreenElement?await document.exitFullscreen():await a.requestFullscreen())}}};return{isPictureInPicture:n!=null?n:!1,togglePictureInPicture:t}};var I=d(require("react"),1),X=(e,n)=>{let[r,t]=I.default.useState(1),u=s=>{t(s)};return I.default.useEffect(()=>{e!=null&&e.current&&t(e.current.playbackRate)},[e==null?void 0:e.current]),I.default.useEffect(()=>{!n||!(e!=null&&e.current)||(e.current.playbackRate=r)},[r,n,e==null?void 0:e.current]),{speed:r,onChangeSpeed:u}};var Z=Y.default.forwardRef(({children:e},n)=>{let{duration:r,showHidingElement:t}=l(),{togglePlay:u,isPlaying:s}=V(n,typeof e=="function"),{speed:o,onChangeSpeed:a}=X(n,typeof e=="function"),{toggleMute:m,isMuted:p}=M(n,typeof e=="function"),{isFullscreen:P,toggleFullscreen:A}=S(),{isPictureInPicture:R,togglePictureInPicture:i}=Q();return typeof e!="function"?null:e({isPlaying:s,togglePlay:u,isMuted:p,toggleMute:m,speed:o,onChangeSpeed:a,isFullscreen:P,toggleFullscreen:A,isPictureInPicture:R,togglePictureInPicture:i,duration:r,showHidingElement:t!=null?t:!1})});var _=d(require("react"),1);var te=require("react/jsx-runtime"),ee=_.default.forwardRef(({children:e,className:n,...r})=>{let{videoRef:t}=l(),{isPlaying:u}=V(t,!0),{showHidingElement:s,setShowHidingElement:o}=l();return(0,te.jsx)("div",{"data-zuude-hiding-element":!0,"data-show":!u||s,className:n,onMouseEnter:()=>{o==null||o(!0)},onMouseLeave:()=>{o==null||o(!1)},...r,children:e})});var x=require("react/jsx-runtime"),re=E.default.forwardRef(({children:e,autoPlay:n,className:r,config:t,ratio:u,controls:s,pause:o,...a},m)=>{let[p,P]=E.default.useState(null),[A,R]=E.default.useState(null),i=m||E.default.useRef(null),[ae,b]=E.default.useState(!1),v=E.default.useRef(null),ce=()=>{var c;(c=i.current)!=null&&c.paused||(b(!0),v.current&&clearTimeout(v.current))},le=()=>{var c;(c=i.current)!=null&&c.paused||(b(!1),v.current&&clearTimeout(v.current))},de=()=>{var c;(c=i.current)!=null&&c.paused||(b(!0),v.current&&clearTimeout(v.current),v.current=setTimeout(()=>{b(!1)},3e3))};return E.default.useEffect(()=>{var c,y;o!==void 0&&(o?(c=i.current)==null||c.pause():(y=i.current)==null||y.play())},[o,i.current]),T(i,n==="force"&&a.muted===void 0&&!(t!=null&&t.autoplayOnVisible),R),w(i,t==null?void 0:t.startAt),j(i,typeof(t==null?void 0:t.autoplayOnVisible)=="number"?t.autoplayOnVisible:void 0,t==null?void 0:t.autoplayOnVisible),(0,x.jsx)(q,{videoRef:i,duration:p,showHidingElement:ae,setShowHidingElement:b,children:(0,x.jsxs)("div",{"data-zuude-video-wrapper":!0,className:r,style:{aspectRatio:u},children:[(0,x.jsx)("video",{"data-zuude-video":!0,ref:i,autoPlay:t!=null&&t.autoplayOnVisible?!1:n==="force"?!0:n,playsInline:!0,onMouseEnter:ce,onMouseLeave:le,onMouseMove:de,onClick:()=>{var c,y,h;t!=null&&t.clickToPlay&&((c=i.current)!=null&&c.paused?(y=i.current)==null||y.play():(h=i.current)==null||h.pause())},onLoadedMetadata:c=>{console.log("loaded metadata"),P(c.target.duration)},onTimeUpdate:c=>{var y;if(t!=null&&t.range){let[h,me]=t.range;if(!(i!=null&&i.current))return;((y=i==null?void 0:i.current)==null?void 0:y.currentTime)<h&&(i.current.currentTime=h),i.current.currentTime>me&&(i.current.currentTime=h)}},className:r,style:{aspectRatio:u},...a}),typeof e=="function"?(0,x.jsx)(Z,{ref:i,children:e}):e,A==="NotAllowedError"&&typeof(t==null?void 0:t.muteFallback)=="function"&&t.muteFallback(()=>{i.current&&(i.current.muted=!i.current.muted),R(null)})]})})});re.displayName="Video";var ne=Object.assign(re,{PlayPauseOnVideo:G,HidingElement:ee});var H=d(require("react"),1);var oe=()=>{let[e,n]=H.default.useState(100),{videoRef:r}=l(),t=u=>{n(u)};return H.default.useEffect(()=>{r!=null&&r.current&&n(r.current.volume*100)},[r==null?void 0:r.current]),H.default.useEffect(()=>{r!=null&&r.current&&(r.current.volume=e/100)},[e,r==null?void 0:r.current]),{volume:e,onChangeVolume:t}};var f=d(require("react"),1);var ue=()=>{let[e,n]=f.default.useState(!1),[r,t]=f.default.useState(0),[u,s]=f.default.useState(0),{videoRef:o,duration:a}=l();return f.default.useEffect(()=>{if(o!=null&&o.current&&e){let m=setInterval(()=>{var p,P;t(((p=o.current)==null?void 0:p.currentTime)||0),(P=o.current)!=null&&P.buffered.length&&s(o.current.buffered.end(o.current.buffered.length-1))},10);return()=>clearInterval(m)}},[o==null?void 0:o.current,e]),f.default.useEffect(()=>{if(o!=null&&o.current)return o.current.addEventListener("play",()=>n(!0)),o.current.addEventListener("pause",()=>n(!1)),()=>{var m,p;(m=o.current)==null||m.removeEventListener("play",()=>n(!0)),(p=o.current)==null||p.removeEventListener("pause",()=>n(!1))}},[]),{currentTime:r,duration:a,buffered:u,setCurrentTime:t}};var k=d(require("react"),1),se=e=>{let[n,r]=k.default.useState(!1),[t,u]=k.default.useState(null);return k.default.useEffect(()=>{if(e!=null&&e.current)return r(!0),e.current.addEventListener("loadedmetadata",()=>{var s,o;u((o=(s=e.current)==null?void 0:s.duration)!=null?o:null),r(!1)}),e.current.addEventListener("error",()=>{r(!1)}),()=>{var s,o;(s=e.current)==null||s.removeEventListener("loadedmetadata",()=>{}),(o=e.current)==null||o.removeEventListener("error",()=>{})}},[e==null?void 0:e.current]),{duration:t,isLoading:n}};function ie(e,n="mm:ss"){let r=Math.floor(e/60),t=Math.floor(e%60);return n==="h:mm:ss"?`${Math.floor(r/60)}:${r}:${t<10?"0":""}${t}`:`${r}:${t<10?"0":""}${t}`}0&&(module.exports={Video,formatTime,useAutoplayByForce,useFullscreen,useGetDuration,useMuteUnmute,usePlayPause,useStartAt,useTimeline,useVideo,useVolume});
|
|
1
|
+
"use strict";"use client";var $=Object.create;var q=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var tt=Object.getPrototypeOf,et=Object.prototype.hasOwnProperty;var rt=(t,e)=>{for(var r in e)q(t,r,{get:e[r],enumerable:!0})},W=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of R(e))!et.call(t,n)&&n!==r&&q(t,n,{get:()=>e[n],enumerable:!(o=v(e,n))||o.enumerable});return t};var C=(t,e,r)=>(r=t!=null?$(tt(t)):{},W(e||!t||!t.__esModule?q(r,"default",{value:t,enumerable:!0}):r,t)),nt=t=>W(q({},"__esModule",{value:!0}),t);var yt={};rt(yt,{Controls:()=>st,ExitFullscreen:()=>pt,Fullscreen:()=>it,Loading:()=>dt,Mute:()=>ct,Pause:()=>ut,Play:()=>ot,SeekBackward:()=>mt,SeekForward:()=>at,Unmute:()=>lt,Video:()=>z,VideoProvider:()=>J});module.exports=nt(yt);var l=C(require("react"),1),O=require("react/jsx-runtime"),G=(0,l.createContext)(null),J=l.default.memo(({children:t,config:e,onError:r,...o})=>{let[n,s]=(0,l.useState)({current:null}),[u,m]=(0,l.useState)(null),[E,g]=(0,l.useState)(!1),M=(0,l.useRef)(null);return(0,l.useEffect)(()=>{r==null||r(u)},[u]),(0,l.useEffect)(()=>{let a=M.current;if(a){let d=a.querySelectorAll("[data-zuude-hide-elements]"),i=a.querySelector("[data-zuude-video]");if(d){let c=null,k=3e3,h=!1,K=()=>{c&&(clearTimeout(c),c=null),c=setTimeout(()=>{h&&i&&!i.paused&&d.forEach(P=>{P.setAttribute("data-hidden","true")}),c=null},k)},S=()=>{h=!0,d.forEach(P=>{P.removeAttribute("data-hidden")}),K()},B=()=>{h=!1,c&&(clearTimeout(c),c=null),i&&!i.paused&&d.forEach(P=>{P.setAttribute("data-hidden","true")})},D=()=>{h&&(d.forEach(P=>{P.hasAttribute("data-hidden")&&P.removeAttribute("data-hidden")}),K())},U=()=>{h||d.forEach(P=>{P.setAttribute("data-hidden","true")})};return a.addEventListener("mouseenter",S),a.addEventListener("mouseleave",B),a.addEventListener("mousemove",D),i.addEventListener("pause",S),i.addEventListener("play",U),()=>{c&&clearTimeout(c),a.removeEventListener("mouseenter",S),a.removeEventListener("mouseleave",B),a.removeEventListener("mousemove",D),i.removeEventListener("pause",S),i.removeEventListener("play",U)}}}},[]),(0,l.useEffect)(()=>{if(E){let a=d=>{var i;(i=M.current)!=null&&i.contains(d.target)||g(!1)};return document.addEventListener("click",a),()=>{document.removeEventListener("click",a)}}},[E]),(0,O.jsx)(G.Provider,{value:{videoRef:n,setVideoRef:s,config:{clickToPlay:!0,...e},error:u,setError:m,isFocused:E,setIsFocused:g},children:(0,O.jsx)("div",{ref:M,"data-zuude-video-wrapper":!0,onClick:()=>g(!0),...o,children:t})})}),p=()=>{let t=(0,l.useContext)(G);if(!t)throw new Error("useVideo must be used within a VideoProvider");return t};var T=require("react");var Q=C(require("react"),1),X=(t,e,r)=>{Q.default.useEffect(()=>{if(!(t!=null&&t.current)||!e)return;(async()=>{var n;try{await((n=t.current)==null?void 0:n.play())}catch(s){if(s instanceof Error&&s.name==="NotAllowedError"){if(r==null||r("NotAllowedError"),console.error("NotAllowedError"),t!=null&&t.current){t.current.muted=!0;try{await t.current.play()}catch(u){console.error(u)}}}else console.error(s)}})()},[e,t==null?void 0:t.current])};var Y=require("react"),L=(t,e,r=!0)=>{let o=n=>{n.key===t&&(n.preventDefault(),e(n))};(0,Y.useEffect)(()=>{if(r)return document.addEventListener("keydown",o),()=>{document.removeEventListener("keydown",o)}},[t,e,r])};var N=C(require("react"),1),f=(t,e=10)=>{let r=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime+=e)},[t==null?void 0:t.current]),o=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime-=e)},[t==null?void 0:t.current]);return{seekForward:r,seekBackward:o}};var F=C(require("react"),1),A=t=>{let[e,r]=F.default.useState(!1),o=F.default.useCallback(()=>{t!=null&&t.current&&(t.current.paused?t.current.play():t.current.pause())},[t==null?void 0:t.current]),n=F.default.useCallback(()=>{t!=null&&t.current&&t.current.play()},[t==null?void 0:t.current]),s=F.default.useCallback(()=>{t!=null&&t.current&&t.current.pause()},[t==null?void 0:t.current]);return F.default.useEffect(()=>{if(!(t!=null&&t.current))return;let u=()=>{r(!0)},m=()=>{r(!1)};if(r(!(t!=null&&t.current.paused)),t!=null&&t.current)return t.current.addEventListener("play",u),t.current.addEventListener("pause",m),()=>{var E,g;(E=t.current)==null||E.removeEventListener("play",u),(g=t.current)==null||g.removeEventListener("pause",m)}},[t==null?void 0:t.current]),{togglePlay:o,isPlaying:e,play:n,pause:s}};var x=C(require("react"),1),I=t=>{let[e,r]=x.default.useState(!1),o=x.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!t.current.muted)},[t==null?void 0:t.current]),n=x.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!0)},[t==null?void 0:t.current]),s=x.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!1)},[t==null?void 0:t.current]);return x.default.useEffect(()=>{if(!(t!=null&&t.current))return;r(t.current.muted);let u=()=>{t.current&&r(t.current.muted)};return t.current.addEventListener("volumechange",u),()=>{var m;(m=t.current)==null||m.removeEventListener("volumechange",u)}},[t==null?void 0:t.current]),{toggleMute:o,isMuted:e,mute:n,unmute:s}};var j=C(require("react"),1),H=t=>{let[e,r]=j.default.useState(!1);j.default.useEffect(()=>{let n=()=>{r==null||r(!!document.fullscreenElement),o()};return document.addEventListener("fullscreenchange",n),()=>document.removeEventListener("fullscreenchange",n)},[e]);let o=()=>{console.log("toggleFullscreen");let n=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),s=t==null?void 0:t.current;if(s&&n){if(s.webkitEnterFullscreen){s.webkitEnterFullscreen();return}else if(s.requestFullscreen){s.requestFullscreen();return}}let u=s==null?void 0:s.closest("[data-zuude-video-wrapper]");u&&(e?(document.exitFullscreen(),s&&(s.style.objectFit="cover")):(u.requestFullscreen(),s&&(s.style.objectFit="contain")))};return{isFullscreen:e!=null?e:!1,toggleFullscreen:o}};var Z=t=>({togglePictureInPicture:async()=>{let n=t==null?void 0:t.current;if(n)try{document.pictureInPictureElement?await document.exitPictureInPicture():await n.requestPictureInPicture()}catch(s){if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent))n.webkitEnterFullscreen?n.webkitEnterFullscreen():n.requestFullscreen&&n.requestFullscreen();else{let m=n.closest("[data-zuude-video-wrapper]");m&&(document.fullscreenElement?await document.exitFullscreen():await m.requestFullscreen())}}},requestPictureInPicture:async()=>{let n=t==null?void 0:t.current;n&&await n.requestPictureInPicture()},exitPictureInPicture:async()=>{t!=null&&t.current&&await document.exitPictureInPicture()}});var _=()=>{let{videoRef:t}=p(),{seekForward:e,seekBackward:r}=f(t),{togglePlay:o}=A(t),{toggleMute:n}=I(t),{toggleFullscreen:s}=H(t),{togglePictureInPicture:u}=Z(t);return L("ArrowRight",()=>{e()}),L("ArrowLeft",()=>{r()}),L(" ",()=>{o()}),L("m",()=>{n()}),L("f",()=>{s()}),L("p",()=>{u()}),null};var w=require("react/jsx-runtime"),z=(0,T.forwardRef)(({src:t,autoPlay:e,muteFallback:r,controls:o,...n},s)=>{let{videoRef:u,setVideoRef:m,config:E,setError:g,error:M,isFocused:a}=p(),d=(0,T.useRef)(null);(0,T.useEffect)(()=>{let c=d.current,k=s;k?m(k):c&&m({current:c})},[t]),X(u,e==="force"&&n.muted===void 0,g);let i=()=>{var c,k,h;(c=u==null?void 0:u.current)!=null&&c.paused?(k=u.current)==null||k.play():(h=u==null?void 0:u.current)==null||h.pause()};return(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)("video",{ref:s||d,"data-zuude-video":!0,src:t,onClick:E!=null&&E.clickToPlay?i:void 0,autoPlay:e==="force"?!0:e,...n}),o&&a&&(0,w.jsx)(_,{}),M==="NotAllowedError"&&typeof r=="function"&&r(()=>{u!=null&&u.current&&(u.current.muted=!u.current.muted),g(null)})]})});z.displayName="Video";var V=C(require("react"),1),b=require("@radix-ui/react-slot");var y=require("react/jsx-runtime"),st=V.default.memo(({children:t,asChild:e,...r})=>(0,y.jsx)("div",{"data-zuude-hide-elements":!0,...r,children:t})),ot=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{play:s}=A(n);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),ut=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{pause:s}=A(n);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),ct=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{mute:s}=I(n);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),lt=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{unmute:s}=I(n);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),at=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{seekForward:s}=f(n,10);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),mt=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{seekBackward:s}=f(n,10);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),it=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{toggleFullscreen:s}=H(n);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),pt=V.default.memo(({children:t,asChild:e,...r})=>{let o=e?b.Slot:"button",{videoRef:n}=p(),{toggleFullscreen:s}=H(n);return(0,y.jsx)(o,{...r,onClick:s,children:t})}),dt=()=>(0,y.jsx)("div",{children:"Loading"});0&&(module.exports={Controls,ExitFullscreen,Fullscreen,Loading,Mute,Pause,Play,SeekBackward,SeekForward,Unmute,Video,VideoProvider});
|
|
3
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","#style-inject:#style-inject","../src/styles.css","../src/video.tsx","../src/context.tsx","../src/hooks/use-autoplay-by-force.tsx","../src/hooks/use-start-at.tsx","../src/hooks/use-autoplay-on-visible.tsx","../src/hooks/use-play-pause.tsx","../src/components/play-pause-on-video.tsx","../src/function-children.tsx","../src/hooks/use-mute-unmute.tsx","../src/hooks/use-fullscreen.tsx","../src/hooks/use-picture-in-picture.tsx","../src/hooks/use-speed.tsx","../src/components/hiding-element.tsx","../src/hooks/use-volume.tsx","../src/hooks/use-timeline.tsx","../src/hooks/use-get-duration.tsx","../src/utils.ts"],"sourcesContent":["\"use client\";\n\nimport \"./styles.css\";\n\nexport { Video } from \"./video\";\n\n// Types\nexport type { VideoProps, VideoContextType } from \"./types\";\n\n// Context\nexport { useVideo } from \"./context\";\n\n// Hooks\nexport { useVolume } from \"./hooks/use-volume\";\nexport { useTimeline } from \"./hooks/use-timeline\";\nexport { useGetDuration } from \"./hooks/use-get-duration\";\nexport { usePlayPause } from \"./hooks/use-play-pause\";\nexport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nexport { useStartAt } from \"./hooks/use-start-at\";\nexport { useFullscreen } from \"./hooks/use-fullscreen\";\nexport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\n\n// Utils\nexport { formatTime } from \"./utils\";\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".reset-styles{box-sizing:border-box;padding:0;margin:0}[data-zuude-video-wrapper]{position:relative}[data-zuude-video-wrapper] [data-zuude-video]{width:100%;height:100%;object-fit:cover}\\n\")","import React from \"react\";\n\n// 📦 Types\nimport type { VideoProps, VideoRef } from \"./types\";\n\n// 🔍 Context\nimport { VideoProvider } from \"./context\";\n\n// 🔗 Hooks\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { useStartAt } from \"./hooks/use-start-at\";\nimport { useAutoplayOnVisible } from \"./hooks/use-autoplay-on-visible\";\n\n// 🔧 Components\nimport { PlayPauseOnVideo } from \"./components/play-pause-on-video\";\nimport { FunctionChildren } from \"./function-children\";\nimport { HidingElement, HidingElementProps } from \"./components/hiding-element\";\n\n/**\n * Main Video component structure\n * @param {VideoProps} props - Video component props\n */\n\nconst VideoComponent = React.forwardRef<\n HTMLVideoElement,\n VideoProps & { pause?: boolean }\n>(\n (\n { children, autoPlay, className, config, ratio, controls, pause, ...props },\n ref\n ) => {\n const [duration, setDuration] = React.useState<number | null>(null);\n const [error, setError] = React.useState<string | null>(null);\n\n const videoRef = (ref as VideoRef) || React.useRef<VideoRef>(null);\n\n const [showHidingElement, setShowHidingElement] = React.useState(false);\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout>>(null);\n const handleMouseEnter = () => {\n if (videoRef.current?.paused) return;\n\n setShowHidingElement(true);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n const handleMouseLeave = () => {\n if (videoRef.current?.paused) return;\n\n setShowHidingElement(false);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n const handleMouseMove = () => {\n if (videoRef.current?.paused) return;\n\n setShowHidingElement(true);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => {\n setShowHidingElement(false);\n }, 3000);\n };\n\n React.useEffect(() => {\n if (pause !== undefined) {\n if (pause) {\n videoRef.current?.pause();\n } else {\n videoRef.current?.play();\n }\n }\n }, [pause, videoRef.current]);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" &&\n props.muted === undefined &&\n !config?.autoplayOnVisible,\n setError\n );\n useStartAt(videoRef, config?.startAt);\n useAutoplayOnVisible(\n videoRef,\n typeof config?.autoplayOnVisible === \"number\"\n ? config.autoplayOnVisible\n : undefined,\n config?.autoplayOnVisible\n );\n\n return (\n <VideoProvider\n videoRef={videoRef}\n duration={duration}\n showHidingElement={showHidingElement}\n setShowHidingElement={setShowHidingElement}\n >\n <div\n data-zuude-video-wrapper\n className={className}\n style={{ aspectRatio: ratio }}\n >\n <video\n data-zuude-video\n // @ts-ignore\n ref={videoRef}\n autoPlay={\n config?.autoplayOnVisible\n ? false\n : autoPlay === \"force\"\n ? true\n : autoPlay\n }\n playsInline\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onMouseMove={handleMouseMove}\n onClick={() => {\n if (config?.clickToPlay) {\n if (videoRef.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef.current?.pause();\n }\n }\n }}\n onLoadedMetadata={(e) => {\n console.log(\"loaded metadata\");\n setDuration((e.target as HTMLVideoElement).duration);\n }}\n onTimeUpdate={(e) => {\n /**\n * If the current time is less than the start time, set the current time to the start time\n * If the current time is greater than the end time, set the current time to the start time\n */\n if (config?.range) {\n const [start, end] = config.range;\n\n if (!videoRef?.current) return;\n\n if (videoRef?.current?.currentTime < start) {\n videoRef.current.currentTime = start;\n }\n\n if (videoRef.current.currentTime > end) {\n videoRef.current.currentTime = start;\n }\n }\n }}\n className={className}\n style={{ aspectRatio: ratio }}\n {...props}\n />\n {typeof children === \"function\" ? (\n <FunctionChildren ref={videoRef} children={children} />\n ) : (\n children\n )}\n {error === \"NotAllowedError\" &&\n typeof config?.muteFallback === \"function\" &&\n config.muteFallback(() => {\n if (videoRef.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </div>\n </VideoProvider>\n );\n }\n);\n\nVideoComponent.displayName = \"Video\";\n\n/**\n * Using compound components pattern\n */\nexport const Video = Object.assign(VideoComponent, {\n PlayPauseOnVideo,\n HidingElement: HidingElement as React.ComponentType<HidingElementProps>,\n});\n","import React from \"react\";\nimport type { VideoContextType } from \"./types.js\";\n\nconst VideoContext = React.createContext<VideoContextType | undefined>(\n undefined\n);\n\nconst useVideo = () => {\n const context = React.useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n\ninterface VideoProviderProps extends VideoContextType {\n children: React.ReactNode;\n}\n\nconst VideoProvider = ({\n children,\n videoRef,\n duration,\n showHidingElement,\n setShowHidingElement,\n}: VideoProviderProps) => {\n const [fullscreen, setFullscreen] = React.useState(false);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n duration,\n isFullscreen: fullscreen,\n setIsFullscreen: setFullscreen,\n showHidingElement,\n setShowHidingElement,\n }}\n >\n {children}\n </VideoContext.Provider>\n );\n};\n\nexport { useVideo, VideoProvider };\n","import React from \"react\";\nimport { VideoRef } from \"../types.js\";\n\nexport const useAutoplayByForce = (\n ref: VideoRef | null,\n enabled: boolean,\n setError?: (error: string | null) => void\n) => {\n React.useEffect(() => {\n if (!ref?.current || !enabled) return;\n\n const playVideo = async () => {\n try {\n await ref.current?.play();\n } catch (error) {\n // If autoplay fails, try muting and playing again\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n setError?.(\"NotAllowedError\");\n console.error(\"NotAllowedError\");\n if (ref?.current) {\n ref.current.muted = true;\n try {\n await ref.current.play();\n } catch (retryError) {\n console.error(retryError);\n }\n }\n } else {\n console.error(error);\n }\n }\n };\n\n playVideo();\n }, [enabled, ref?.current]);\n};\n","import React from \"react\";\nimport type { VideoConfig, VideoRef } from \"../types\";\n\nexport const useStartAt = (ref: VideoRef, startAt?: VideoConfig[\"startAt\"]) => {\n React.useEffect(() => {\n if (!ref?.current || !startAt) return;\n\n const video = ref?.current;\n if (video && startAt) {\n video.currentTime = startAt;\n }\n }, [startAt, ref?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayOnVisible = (\n ref: VideoRef,\n threshold: number | undefined,\n enabled: boolean | number | null | undefined\n) => {\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (!ref?.current) return;\n\n if (entry.isIntersecting) {\n ref.current.play().catch((error) => {\n if (!ref.current) return;\n\n ref.current.pause();\n ref.current.muted = true;\n ref.current.play();\n console.error(error);\n });\n } else {\n ref.current?.pause();\n }\n });\n },\n { threshold: threshold ?? 0.5 }\n );\n\n observer.observe(ref?.current);\n\n return () => {\n observer.disconnect();\n };\n }, [enabled, ref?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const usePlayPause = (ref: VideoRef, enabled: boolean) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n\n const togglePlay = React.useCallback(() => {\n console.log(ref?.current);\n if (ref?.current) {\n ref.current.paused ? ref.current.play() : ref.current.pause();\n }\n }, [ref?.current]);\n\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n const handlePlay = () => {\n setIsPlaying(true);\n };\n const handlePause = () => {\n setIsPlaying(false);\n };\n\n setIsPlaying(!ref?.current.paused);\n\n if (ref?.current) {\n ref.current.addEventListener(\"play\", handlePlay);\n ref.current.addEventListener(\"pause\", handlePause);\n\n return () => {\n ref.current?.removeEventListener(\"play\", handlePlay);\n ref.current?.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [ref?.current, enabled]);\n\n return { togglePlay, isPlaying };\n};\n","import { useVideo } from \"../context\";\nimport { usePlayPause } from \"../hooks/use-play-pause\";\n\nexport const PlayPauseOnVideo = () => {\n const { videoRef } = useVideo();\n\n const { togglePlay } = usePlayPause(videoRef, true);\n\n return (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n onClick={togglePlay}\n ></div>\n );\n};\n","import React from \"react\";\n\nimport type { VideoChildren, VideoRef } from \"./types\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useVideo } from \"./context\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\nimport { useSpeed } from \"./hooks/use-speed\";\n\nexport const FunctionChildren = React.forwardRef<\n any,\n {\n children: VideoChildren;\n }\n>(({ children }, ref) => {\n const { duration, showHidingElement } = useVideo();\n\n /**\n * Only use these hooks if the children is a function\n */\n const { togglePlay, isPlaying } = usePlayPause(\n ref as VideoRef,\n typeof children === \"function\"\n );\n const { speed, onChangeSpeed } = useSpeed(\n ref as VideoRef,\n typeof children === \"function\"\n );\n const { toggleMute, isMuted } = useMuteUnmute(\n ref as VideoRef,\n typeof children === \"function\"\n );\n const { isFullscreen, toggleFullscreen } = useFullscreen();\n const { isPictureInPicture, togglePictureInPicture } = usePictureInPicture();\n\n if (typeof children !== \"function\") return null;\n\n return children({\n isPlaying,\n togglePlay,\n isMuted,\n toggleMute,\n speed,\n onChangeSpeed,\n isFullscreen,\n toggleFullscreen,\n isPictureInPicture,\n togglePictureInPicture,\n duration,\n showHidingElement: showHidingElement ?? false,\n });\n});\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useMuteUnmute = (ref: VideoRef, enabled: boolean) => {\n const [isMuted, setIsMuted] = React.useState(false);\n\n const toggleMute = React.useCallback(() => {\n if (ref?.current) {\n ref.current.muted = !ref.current.muted;\n }\n }, [ref?.current]);\n\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n // Set the initial state\n setIsMuted(ref.current.muted);\n\n const handleVolumeChange = () => {\n if (ref.current) {\n setIsMuted(ref.current.muted);\n }\n };\n\n ref.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n ref.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [ref?.current, enabled]);\n\n return { toggleMute, isMuted };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const useFullscreen = () => {\n const { videoRef, isFullscreen, setIsFullscreen } = useVideo();\n\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen?.(!!document.fullscreenElement);\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const video = videoRef?.current;\n\n if (video && isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n return;\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n return;\n }\n }\n\n const videoContainer = videoRef?.current?.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n\n if (videoContainer) {\n if (!isFullscreen) {\n videoContainer.requestFullscreen();\n } else {\n document.exitFullscreen();\n }\n }\n };\n\n return { isFullscreen: isFullscreen ?? false, toggleFullscreen };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const usePictureInPicture = () => {\n const { videoRef, isPictureInPicture, setIsPictureInPicture } = useVideo();\n\n React.useEffect(() => {\n const handlePictureInPictureChange = () => {\n setIsPictureInPicture?.(!!document.pictureInPictureElement);\n };\n\n document.addEventListener(\n \"pictureinpicturechange\",\n handlePictureInPictureChange\n );\n return () =>\n document.removeEventListener(\n \"pictureinpicturechange\",\n handlePictureInPictureChange\n );\n }, []);\n\n const togglePictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await video.requestPictureInPicture();\n }\n } catch (error) {\n // Fallback for browsers that don't support PiP\n const isSafari = /^((?!chrome|android).)*safari/i.test(\n navigator.userAgent\n );\n\n if (isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n }\n } else {\n const videoContainer = video.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n if (videoContainer) {\n if (!document.fullscreenElement) {\n await videoContainer.requestFullscreen();\n } else {\n await document.exitFullscreen();\n }\n }\n }\n }\n };\n\n return {\n isPictureInPicture: isPictureInPicture ?? false,\n togglePictureInPicture,\n };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSpeed = (ref: VideoRef, enabled: boolean) => {\n const [speed, setSpeed] = React.useState(1);\n\n const onChangeSpeed = (speed: number) => {\n setSpeed(speed);\n };\n\n // Get the speed from the video element\n React.useEffect(() => {\n if (!ref?.current) return;\n setSpeed(ref.current.playbackRate);\n }, [ref?.current]);\n\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n ref.current.playbackRate = speed;\n }, [speed, enabled, ref?.current]);\n\n return { speed, onChangeSpeed };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\nimport { usePlayPause } from \"../hooks/use-play-pause\";\n\nexport interface HidingElementProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n children: React.ReactNode;\n className?: string;\n}\n\nexport const HidingElement = React.forwardRef<\n HTMLDivElement,\n HidingElementProps\n>(({ children, className, ...props }: HidingElementProps) => {\n const { videoRef } = useVideo();\n const { isPlaying } = usePlayPause(videoRef, true);\n const { showHidingElement, setShowHidingElement } = useVideo();\n\n return (\n <div\n data-zuude-hiding-element\n data-show={!isPlaying || showHidingElement}\n className={className}\n onMouseEnter={() => {\n setShowHidingElement?.(true);\n }}\n onMouseLeave={() => {\n setShowHidingElement?.(false);\n }}\n {...props}\n >\n {children}\n </div>\n );\n});\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const useVolume = () => {\n const [volume, setVolume] = React.useState(100);\n const { videoRef } = useVideo();\n\n const onChangeVolume = (volume: number) => {\n setVolume(volume);\n };\n\n // Get the volume from the video element\n React.useEffect(() => {\n if (!videoRef?.current) return;\n setVolume(videoRef.current.volume * 100);\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.volume = volume / 100;\n }, [volume, videoRef?.current]);\n\n return { volume, onChangeVolume };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const useTimeline = () => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [buffered, setBuffered] = React.useState(0);\n\n const { videoRef, duration } = useVideo();\n\n React.useEffect(() => {\n if (videoRef?.current && isPlaying) {\n const intervalId = setInterval(() => {\n setCurrentTime(videoRef.current?.currentTime || 0);\n\n if (videoRef.current?.buffered.length) {\n setBuffered(\n videoRef.current.buffered.end(videoRef.current.buffered.length - 1)\n );\n }\n }, 10);\n\n return () => clearInterval(intervalId);\n }\n }, [videoRef?.current, isPlaying]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.addEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current.addEventListener(\"pause\", () => setIsPlaying(false));\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current?.removeEventListener(\"pause\", () => setIsPlaying(false));\n };\n }, []);\n\n return {\n currentTime,\n duration,\n buffered,\n setCurrentTime,\n };\n};\n","import React from \"react\";\nimport { VideoRef } from \"../types.js\";\n\nexport const useGetDuration = (ref: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n const [duration, setDuration] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!ref?.current) return;\n setIsLoading(true);\n\n ref.current.addEventListener(\"loadedmetadata\", () => {\n setDuration(ref.current?.duration ?? null);\n setIsLoading(false);\n });\n\n ref.current.addEventListener(\"error\", () => {\n setIsLoading(false);\n });\n\n return () => {\n ref.current?.removeEventListener(\"loadedmetadata\", () => {});\n ref.current?.removeEventListener(\"error\", () => {});\n };\n }, [ref?.current]);\n\n return { duration, isLoading };\n};\n","function formatTime(time: number, type: \"h:mm:ss\" | \"mm:ss\" = \"mm:ss\"): string {\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n if (type === \"h:mm:ss\") {\n const hours = Math.floor(minutes / 60);\n return `${hours}:${minutes}:${seconds < 10 ? \"0\" : \"\"}${seconds}`;\n }\n return `${minutes}:${seconds < 10 ? \"0\" : \"\"}${seconds}`;\n}\n\nexport { formatTime };\n"],"mappings":"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","names":["index_exports","__export","Video","formatTime","useAutoplayByForce","useFullscreen","useGetDuration","useMuteUnmute","usePlayPause","useStartAt","useTimeline","useVideo","useVolume","__toCommonJS","styleInject","css","insertAt","head","style","styleInject","import_react","import_react","import_jsx_runtime","VideoContext","React","useVideo","context","VideoProvider","children","videoRef","duration","showHidingElement","setShowHidingElement","fullscreen","setFullscreen","import_react","useAutoplayByForce","ref","enabled","setError","React","_a","error","retryError","import_react","useStartAt","ref","startAt","React","video","import_react","useAutoplayOnVisible","ref","threshold","enabled","React","observer","entries","entry","_a","error","import_react","usePlayPause","ref","enabled","isPlaying","setIsPlaying","React","togglePlay","handlePlay","handlePause","_a","_b","import_jsx_runtime","PlayPauseOnVideo","videoRef","useVideo","togglePlay","usePlayPause","import_react","import_react","useMuteUnmute","ref","enabled","isMuted","setIsMuted","React","toggleMute","handleVolumeChange","_a","import_react","useFullscreen","videoRef","isFullscreen","setIsFullscreen","useVideo","React","handleFullscreenChange","toggleFullscreen","_a","isSafari","video","videoContainer","import_react","usePictureInPicture","videoRef","isPictureInPicture","setIsPictureInPicture","useVideo","React","handlePictureInPictureChange","togglePictureInPicture","video","error","videoContainer","import_react","useSpeed","ref","enabled","speed","setSpeed","React","onChangeSpeed","FunctionChildren","React","children","ref","duration","showHidingElement","useVideo","togglePlay","isPlaying","usePlayPause","speed","onChangeSpeed","useSpeed","toggleMute","isMuted","useMuteUnmute","isFullscreen","toggleFullscreen","useFullscreen","isPictureInPicture","togglePictureInPicture","usePictureInPicture","import_react","import_jsx_runtime","HidingElement","React","children","className","props","videoRef","useVideo","isPlaying","usePlayPause","showHidingElement","setShowHidingElement","import_jsx_runtime","VideoComponent","React","children","autoPlay","className","config","ratio","controls","pause","props","ref","duration","setDuration","error","setError","videoRef","showHidingElement","setShowHidingElement","timeoutRef","handleMouseEnter","_a","handleMouseLeave","handleMouseMove","_b","useAutoplayByForce","useStartAt","useAutoplayOnVisible","VideoProvider","_c","e","start","end","FunctionChildren","Video","PlayPauseOnVideo","HidingElement","import_react","useVolume","volume","setVolume","React","videoRef","useVideo","onChangeVolume","import_react","useTimeline","isPlaying","setIsPlaying","React","currentTime","setCurrentTime","buffered","setBuffered","videoRef","duration","useVideo","intervalId","_a","_b","import_react","useGetDuration","ref","isLoading","setIsLoading","React","duration","setDuration","_a","_b","formatTime","time","type","minutes","seconds"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/wrapper.tsx","../src/video.tsx","../src/hooks/use-autoplay-by-force.tsx","../src/hooks/use-hot-keys.tsx","../src/hooks/use-seek.tsx","../src/hooks/use-play-pause.tsx","../src/hooks/use-mute-unmute.tsx","../src/hooks/use-fullscreen.tsx","../src/hooks/use-picture-in-picture.tsx","../src/keyboard.tsx","../src/components.tsx"],"sourcesContent":["\"use client\";\n\nexport { VideoProvider } from \"./wrapper\";\nexport { Video } from \"./video\";\nexport * from \"./components\";\nexport * from \"./types\";\n","import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { VideoRef } from \"./types\";\n\ninterface VideoConfig {\n config?: Partial<{\n clickToPlay: boolean;\n }>;\n}\n\ninterface VideoContextType extends VideoConfig {\n videoRef: VideoRef;\n setVideoRef: (video: VideoRef) => void;\n error: string | null;\n setError: (error: string | null) => void;\n isFocused: boolean;\n setIsFocused: (isFocused: boolean) => void;\n}\n\nexport const VideoContext = createContext<VideoContextType | null>(null);\n\ntype VideoProviderProps = Omit<React.ComponentProps<\"div\">, \"onError\"> &\n VideoConfig & {\n children: React.ReactNode;\n onError?: (error: string | null) => void;\n };\n\nexport const VideoProvider = React.memo(\n ({ children, config, onError, ...props }: VideoProviderProps) => {\n const [videoRef, setVideoRef] = useState<VideoRef>({ current: null });\n const [error, setError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n const videoWrapperRef = useRef<HTMLDivElement>(null);\n\n // Sending error to user if it exists\n useEffect(() => {\n onError?.(error);\n }, [error]);\n\n useEffect(() => {\n const videoWrapper = videoWrapperRef.current;\n if (videoWrapper) {\n const controls = videoWrapper.querySelectorAll(\n \"[data-zuude-hide-elements]\"\n );\n const video = videoWrapper.querySelector(\n \"[data-zuude-video]\"\n ) as HTMLVideoElement;\n\n if (controls) {\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n const hideDelay = 3000; // 3 seconds delay\n let isMouseOver = false;\n\n const resetTimer = () => {\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n\n // Start new timer to hide controls after delay\n hideTimeout = setTimeout(() => {\n if (isMouseOver) {\n // Check if video is paused - don't hide controls if paused\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n }\n hideTimeout = null;\n }, hideDelay);\n };\n\n const showControls = () => {\n isMouseOver = true;\n controls.forEach((control) => {\n control.removeAttribute(\"data-hidden\");\n });\n resetTimer();\n };\n\n const hideControls = () => {\n isMouseOver = false;\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n // Hide controls immediately when mouse leaves\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n const handleMouseMove = () => {\n if (isMouseOver) {\n // If controls are hidden, show them\n controls.forEach((control) => {\n if (control.hasAttribute(\"data-hidden\")) {\n control.removeAttribute(\"data-hidden\");\n }\n });\n resetTimer();\n }\n };\n\n const handlePlay = () => {\n // Hide controls when video starts playing (autoplay)\n if (!isMouseOver) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n videoWrapper.addEventListener(\"mouseenter\", showControls);\n videoWrapper.addEventListener(\"mouseleave\", hideControls);\n videoWrapper.addEventListener(\"mousemove\", handleMouseMove);\n video.addEventListener(\"pause\", showControls);\n video.addEventListener(\"play\", handlePlay);\n\n // Cleanup function\n return () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n videoWrapper.removeEventListener(\"mouseenter\", showControls);\n videoWrapper.removeEventListener(\"mouseleave\", hideControls);\n videoWrapper.removeEventListener(\"mousemove\", handleMouseMove);\n video.removeEventListener(\"pause\", showControls);\n video.removeEventListener(\"play\", handlePlay);\n };\n }\n }\n }, []);\n\n useEffect(() => {\n if (isFocused) {\n const handleClick = (event: MouseEvent) => {\n if (!videoWrapperRef.current?.contains(event.target as Node)) {\n setIsFocused(false);\n }\n };\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n document.removeEventListener(\"click\", handleClick);\n };\n }\n }, [isFocused]);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n setVideoRef,\n config: { clickToPlay: true, ...config },\n error,\n setError,\n isFocused,\n setIsFocused,\n }}\n >\n <div\n ref={videoWrapperRef}\n data-zuude-video-wrapper\n onClick={() => setIsFocused(true)}\n {...props}\n >\n {children}\n </div>\n </VideoContext.Provider>\n );\n }\n);\n\nexport const useVideo = () => {\n const context = useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n","import React, { forwardRef, RefObject, useEffect, useRef } from \"react\";\nimport { useVideo } from \"./wrapper\";\nimport { VideoAutoplay } from \"./types\";\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { Keyboards } from \"./keyboard\";\n\ninterface Props extends Omit<React.ComponentProps<\"video\">, \"autoPlay\"> {\n src: string;\n autoPlay?: VideoAutoplay;\n controls?: boolean;\n muteFallback?: (onMute: () => void) => React.ReactNode;\n}\n\nexport const Video = forwardRef<HTMLVideoElement, Props>(\n ({ src, autoPlay, muteFallback, controls, ...props }, ref) => {\n const { videoRef, setVideoRef, config, setError, error, isFocused } =\n useVideo();\n\n const refVideo = useRef<HTMLVideoElement>(null);\n\n useEffect(() => {\n const video = refVideo.current;\n const thirdPartyRef = ref;\n\n if (thirdPartyRef) {\n setVideoRef(thirdPartyRef as RefObject<HTMLVideoElement>);\n } else {\n if (video) {\n setVideoRef({ current: video });\n }\n }\n }, [src]);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" && props.muted === undefined,\n setError\n );\n\n const onPlay = () => {\n if (videoRef?.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef?.current?.pause();\n }\n };\n\n return (\n <>\n <video\n ref={ref || refVideo}\n data-zuude-video\n src={src}\n onClick={config?.clickToPlay ? onPlay : undefined}\n autoPlay={autoPlay === \"force\" ? true : autoPlay}\n {...props}\n />\n\n {controls && isFocused && <Keyboards />}\n\n {error === \"NotAllowedError\" &&\n typeof muteFallback === \"function\" &&\n muteFallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </>\n );\n }\n);\n\nVideo.displayName = \"Video\";\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayByForce = (\n videoRef: VideoRef,\n enabled: boolean,\n setError?: (error: string | null) => void\n) => {\n React.useEffect(() => {\n if (!videoRef?.current || !enabled) return;\n\n const playVideo = async () => {\n try {\n await videoRef.current?.play();\n } catch (error) {\n // If autoplay fails, try muting and playing again\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n setError?.(\"NotAllowedError\");\n console.error(\"NotAllowedError\");\n if (videoRef?.current) {\n videoRef.current.muted = true;\n try {\n await videoRef.current.play();\n } catch (retryError) {\n console.error(retryError);\n }\n }\n } else {\n console.error(error);\n }\n }\n };\n\n playVideo();\n }, [enabled, videoRef?.current]);\n};\n","import { useEffect } from \"react\";\n\nexport const useHotKeys = (\n key: string,\n func: (event: KeyboardEvent) => void,\n enabled = true\n) => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === key) {\n event.preventDefault();\n func(event);\n }\n };\n\n useEffect(() => {\n if (!enabled) return;\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [key, func, enabled]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSeek = (videoRef: VideoRef, value = 10) => {\n const seekForward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime += value;\n }\n }, [videoRef?.current]);\n\n const seekBackward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime -= value;\n }\n }, [videoRef?.current]);\n\n return { seekForward, seekBackward };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const usePlayPause = (videoRef: VideoRef) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n\n const togglePlay = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.paused\n ? videoRef.current.play()\n : videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n const play = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.play();\n }\n }, [videoRef?.current]);\n\n const pause = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const handlePlay = () => {\n setIsPlaying(true);\n };\n const handlePause = () => {\n setIsPlaying(false);\n };\n\n setIsPlaying(!videoRef?.current.paused);\n\n if (videoRef?.current) {\n videoRef.current.addEventListener(\"play\", handlePlay);\n videoRef.current.addEventListener(\"pause\", handlePause);\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", handlePlay);\n videoRef.current?.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n return { togglePlay, isPlaying, play, pause };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useMuteUnmute = (videoRef: VideoRef) => {\n const [isMuted, setIsMuted] = React.useState(false);\n\n const toggleMute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, [videoRef?.current]);\n\n const mute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = true;\n }\n }, [videoRef?.current]);\n\n const unmute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = false;\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n // Set the initial state\n setIsMuted(videoRef.current.muted);\n\n const handleVolumeChange = () => {\n if (videoRef.current) {\n setIsMuted(videoRef.current.muted);\n }\n };\n\n videoRef.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n videoRef.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [videoRef?.current]);\n\n return { toggleMute, isMuted, mute, unmute };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nconst useFullscreen = (videoRef: VideoRef) => {\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen?.(!!document.fullscreenElement);\n toggleFullscreen();\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, [isFullscreen]);\n\n const toggleFullscreen = () => {\n console.log(\"toggleFullscreen\");\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const video = videoRef?.current;\n\n if (video && isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n return;\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n return;\n }\n }\n\n const videoContainer = video?.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n\n if (videoContainer) {\n if (!isFullscreen) {\n videoContainer.requestFullscreen();\n if (video) {\n video.style.objectFit = \"contain\";\n }\n } else {\n document.exitFullscreen();\n if (video) {\n video.style.objectFit = \"cover\";\n }\n }\n }\n };\n\n return { isFullscreen: isFullscreen ?? false, toggleFullscreen };\n};\n\nexport { useFullscreen };\n","import type { VideoRef } from \"../types\";\n\nexport const usePictureInPicture = (videoRef: VideoRef) => {\n const togglePictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await video.requestPictureInPicture();\n }\n } catch (error) {\n // Fallback for browsers that don't support PiP\n const isSafari = /^((?!chrome|android).)*safari/i.test(\n navigator.userAgent\n );\n\n if (isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n }\n } else {\n const videoContainer = video.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n if (videoContainer) {\n if (!document.fullscreenElement) {\n await videoContainer.requestFullscreen();\n } else {\n await document.exitFullscreen();\n }\n }\n }\n }\n };\n\n const requestPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await video.requestPictureInPicture();\n };\n\n const exitPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await document.exitPictureInPicture();\n };\n\n return {\n togglePictureInPicture,\n requestPictureInPicture,\n exitPictureInPicture,\n };\n};\n","import { useVideo } from \"./wrapper\";\nimport { useHotKeys } from \"./hooks/use-hot-keys\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\n\nexport const Keyboards = () => {\n const { videoRef } = useVideo();\n\n const { seekForward, seekBackward } = useSeek(videoRef);\n const { togglePlay } = usePlayPause(videoRef);\n const { toggleMute } = useMuteUnmute(videoRef);\n const { toggleFullscreen } = useFullscreen(videoRef);\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n useHotKeys(\"ArrowRight\", () => {\n seekForward();\n });\n useHotKeys(\"ArrowLeft\", () => {\n seekBackward();\n });\n useHotKeys(\" \", () => {\n togglePlay();\n });\n useHotKeys(\"m\", () => {\n toggleMute();\n });\n useHotKeys(\"f\", () => {\n toggleFullscreen();\n });\n useHotKeys(\"p\", () => {\n togglePictureInPicture();\n });\n\n return null;\n};\n","import React, { RefObject } from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useVideo } from \"./wrapper\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\n\ninterface ControlsProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Controls = React.memo(\n ({ children, asChild, ...props }: ControlsProps) => {\n return (\n <div data-zuude-hide-elements {...props}>\n {children}\n </div>\n );\n }\n);\n\ninterface Props extends React.ComponentProps<\"button\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Play = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { play } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={play}>\n {children}\n </Element>\n );\n});\n\nconst Pause = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { pause } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={pause}>\n {children}\n </Element>\n );\n});\n\nconst Mute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { mute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={mute}>\n {children}\n </Element>\n );\n});\n\nconst Unmute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { unmute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={unmute}>\n {children}\n </Element>\n );\n});\n\nconst SeekForward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekForward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekForward}>\n {children}\n </Element>\n );\n});\n\nconst SeekBackward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekBackward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekBackward}>\n {children}\n </Element>\n );\n});\n\nconst Fullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst ExitFullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst Loading = () => {\n return <div>Loading</div>;\n};\n\nexport {\n Controls,\n Play,\n Pause,\n Mute,\n Unmute,\n SeekForward,\n SeekBackward,\n Fullscreen,\n ExitFullscreen,\n Loading,\n};\n"],"mappings":"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","names":["index_exports","__export","Controls","ExitFullscreen","Fullscreen","Loading","Mute","Pause","Play","SeekBackward","SeekForward","Unmute","Video","VideoProvider","__toCommonJS","import_react","import_jsx_runtime","VideoContext","VideoProvider","React","children","config","onError","props","videoRef","setVideoRef","error","setError","isFocused","setIsFocused","videoWrapperRef","videoWrapper","controls","video","hideTimeout","hideDelay","isMouseOver","resetTimer","control","showControls","hideControls","handleMouseMove","handlePlay","handleClick","event","_a","useVideo","context","import_react","import_react","useAutoplayByForce","videoRef","enabled","setError","React","_a","error","retryError","import_react","useHotKeys","key","func","enabled","handleKeyDown","event","import_react","useSeek","videoRef","value","seekForward","React","seekBackward","import_react","usePlayPause","videoRef","isPlaying","setIsPlaying","React","togglePlay","play","pause","handlePlay","handlePause","_a","_b","import_react","useMuteUnmute","videoRef","isMuted","setIsMuted","React","toggleMute","mute","unmute","handleVolumeChange","_a","import_react","useFullscreen","videoRef","isFullscreen","setIsFullscreen","React","handleFullscreenChange","toggleFullscreen","isSafari","video","videoContainer","usePictureInPicture","videoRef","video","error","videoContainer","Keyboards","videoRef","useVideo","seekForward","seekBackward","useSeek","togglePlay","usePlayPause","toggleMute","useMuteUnmute","toggleFullscreen","useFullscreen","togglePictureInPicture","usePictureInPicture","useHotKeys","import_jsx_runtime","Video","src","autoPlay","muteFallback","controls","props","ref","videoRef","setVideoRef","config","setError","error","isFocused","useVideo","refVideo","video","thirdPartyRef","useAutoplayByForce","onPlay","_a","_b","_c","Keyboards","import_react","import_react_slot","import_jsx_runtime","Controls","React","children","asChild","props","Play","Element","videoRef","useVideo","play","usePlayPause","Pause","pause","Mute","mute","useMuteUnmute","Unmute","unmute","SeekForward","seekForward","useSeek","SeekBackward","seekBackward","Fullscreen","toggleFullscreen","useFullscreen","ExitFullscreen","Loading"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,102 +1,48 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { RefObject } from 'react';
|
|
3
3
|
|
|
4
4
|
type VideoAutoplay = boolean | "force";
|
|
5
|
-
type
|
|
5
|
+
type CustomVideoRef = RefObject<(Omit<HTMLVideoElement, "autoplay"> & {
|
|
6
6
|
autoplay?: VideoAutoplay;
|
|
7
7
|
}) | null>;
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
isPictureInPicture: boolean;
|
|
19
|
-
togglePictureInPicture: () => void;
|
|
20
|
-
showHidingElement: boolean;
|
|
21
|
-
}) => ReactNode);
|
|
22
|
-
type VideoConfig = {
|
|
23
|
-
startAt?: number;
|
|
24
|
-
range?: [number, number];
|
|
25
|
-
autoplayOnVisible?: boolean | number;
|
|
26
|
-
muteFallback?: (toggleMute: () => void) => ReactNode;
|
|
27
|
-
clickToPlay?: boolean;
|
|
8
|
+
type VideoRef = RefObject<HTMLVideoElement | null> | null;
|
|
9
|
+
|
|
10
|
+
interface VideoConfig {
|
|
11
|
+
config?: Partial<{
|
|
12
|
+
clickToPlay: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
type VideoProviderProps = Omit<React.ComponentProps<"div">, "onError"> & VideoConfig & {
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
onError?: (error: string | null) => void;
|
|
28
18
|
};
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
declare const VideoProvider: React.MemoExoticComponent<({ children, config, onError, ...props }: VideoProviderProps) => react_jsx_runtime.JSX.Element>;
|
|
20
|
+
|
|
21
|
+
interface Props$1 extends Omit<React.ComponentProps<"video">, "autoPlay"> {
|
|
22
|
+
src: string;
|
|
31
23
|
autoPlay?: VideoAutoplay;
|
|
32
|
-
ratio?: string;
|
|
33
|
-
config?: VideoConfig;
|
|
34
24
|
controls?: boolean;
|
|
25
|
+
muteFallback?: (onMute: () => void) => React.ReactNode;
|
|
35
26
|
}
|
|
36
|
-
|
|
37
|
-
videoRef: VideoRef;
|
|
38
|
-
duration: number | null;
|
|
39
|
-
isFullscreen?: boolean;
|
|
40
|
-
setIsFullscreen?: (isFullscreen: boolean) => void;
|
|
41
|
-
isPictureInPicture?: boolean;
|
|
42
|
-
setIsPictureInPicture?: (isPictureInPicture: boolean) => void;
|
|
43
|
-
showHidingElement?: boolean;
|
|
44
|
-
setShowHidingElement?: (showHidingElement: boolean) => void;
|
|
45
|
-
}
|
|
27
|
+
declare const Video: React.ForwardRefExoticComponent<Omit<Props$1, "ref"> & React.RefAttributes<HTMLVideoElement>>;
|
|
46
28
|
|
|
47
|
-
interface
|
|
29
|
+
interface ControlsProps extends React.ComponentProps<"div"> {
|
|
48
30
|
children: React.ReactNode;
|
|
49
|
-
|
|
31
|
+
asChild?: boolean;
|
|
50
32
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
declare const
|
|
63
|
-
|
|
64
|
-
declare const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
declare const useTimeline: () => {
|
|
70
|
-
currentTime: number;
|
|
71
|
-
duration: number | null;
|
|
72
|
-
buffered: number;
|
|
73
|
-
setCurrentTime: React.Dispatch<React.SetStateAction<number>>;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
declare const useGetDuration: (ref: VideoRef) => {
|
|
77
|
-
duration: number | null;
|
|
78
|
-
isLoading: boolean;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
declare const usePlayPause: (ref: VideoRef, enabled: boolean) => {
|
|
82
|
-
togglePlay: () => void;
|
|
83
|
-
isPlaying: boolean;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
declare const useMuteUnmute: (ref: VideoRef, enabled: boolean) => {
|
|
87
|
-
toggleMute: () => void;
|
|
88
|
-
isMuted: boolean;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
declare const useStartAt: (ref: VideoRef, startAt?: VideoConfig["startAt"]) => void;
|
|
92
|
-
|
|
93
|
-
declare const useFullscreen: () => {
|
|
94
|
-
isFullscreen: boolean;
|
|
95
|
-
toggleFullscreen: () => void;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
declare const useAutoplayByForce: (ref: VideoRef | null, enabled: boolean, setError?: (error: string | null) => void) => void;
|
|
99
|
-
|
|
100
|
-
declare function formatTime(time: number, type?: "h:mm:ss" | "mm:ss"): string;
|
|
101
|
-
|
|
102
|
-
export { Video, type VideoContextType, type VideoProps, formatTime, useAutoplayByForce, useFullscreen, useGetDuration, useMuteUnmute, usePlayPause, useStartAt, useTimeline, useVideo, useVolume };
|
|
33
|
+
declare const Controls: React.MemoExoticComponent<({ children, asChild, ...props }: ControlsProps) => react_jsx_runtime.JSX.Element>;
|
|
34
|
+
interface Props extends React.ComponentProps<"button"> {
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
asChild?: boolean;
|
|
37
|
+
}
|
|
38
|
+
declare const Play: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
39
|
+
declare const Pause: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
40
|
+
declare const Mute: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
41
|
+
declare const Unmute: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
42
|
+
declare const SeekForward: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
43
|
+
declare const SeekBackward: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
44
|
+
declare const Fullscreen: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
45
|
+
declare const ExitFullscreen: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
46
|
+
declare const Loading: () => react_jsx_runtime.JSX.Element;
|
|
47
|
+
|
|
48
|
+
export { Controls, type CustomVideoRef, ExitFullscreen, Fullscreen, Loading, Mute, Pause, Play, SeekBackward, SeekForward, Unmute, Video, type VideoAutoplay, VideoProvider, type VideoRef };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,102 +1,48 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { RefObject } from 'react';
|
|
3
3
|
|
|
4
4
|
type VideoAutoplay = boolean | "force";
|
|
5
|
-
type
|
|
5
|
+
type CustomVideoRef = RefObject<(Omit<HTMLVideoElement, "autoplay"> & {
|
|
6
6
|
autoplay?: VideoAutoplay;
|
|
7
7
|
}) | null>;
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
isPictureInPicture: boolean;
|
|
19
|
-
togglePictureInPicture: () => void;
|
|
20
|
-
showHidingElement: boolean;
|
|
21
|
-
}) => ReactNode);
|
|
22
|
-
type VideoConfig = {
|
|
23
|
-
startAt?: number;
|
|
24
|
-
range?: [number, number];
|
|
25
|
-
autoplayOnVisible?: boolean | number;
|
|
26
|
-
muteFallback?: (toggleMute: () => void) => ReactNode;
|
|
27
|
-
clickToPlay?: boolean;
|
|
8
|
+
type VideoRef = RefObject<HTMLVideoElement | null> | null;
|
|
9
|
+
|
|
10
|
+
interface VideoConfig {
|
|
11
|
+
config?: Partial<{
|
|
12
|
+
clickToPlay: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
type VideoProviderProps = Omit<React.ComponentProps<"div">, "onError"> & VideoConfig & {
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
onError?: (error: string | null) => void;
|
|
28
18
|
};
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
declare const VideoProvider: React.MemoExoticComponent<({ children, config, onError, ...props }: VideoProviderProps) => react_jsx_runtime.JSX.Element>;
|
|
20
|
+
|
|
21
|
+
interface Props$1 extends Omit<React.ComponentProps<"video">, "autoPlay"> {
|
|
22
|
+
src: string;
|
|
31
23
|
autoPlay?: VideoAutoplay;
|
|
32
|
-
ratio?: string;
|
|
33
|
-
config?: VideoConfig;
|
|
34
24
|
controls?: boolean;
|
|
25
|
+
muteFallback?: (onMute: () => void) => React.ReactNode;
|
|
35
26
|
}
|
|
36
|
-
|
|
37
|
-
videoRef: VideoRef;
|
|
38
|
-
duration: number | null;
|
|
39
|
-
isFullscreen?: boolean;
|
|
40
|
-
setIsFullscreen?: (isFullscreen: boolean) => void;
|
|
41
|
-
isPictureInPicture?: boolean;
|
|
42
|
-
setIsPictureInPicture?: (isPictureInPicture: boolean) => void;
|
|
43
|
-
showHidingElement?: boolean;
|
|
44
|
-
setShowHidingElement?: (showHidingElement: boolean) => void;
|
|
45
|
-
}
|
|
27
|
+
declare const Video: React.ForwardRefExoticComponent<Omit<Props$1, "ref"> & React.RefAttributes<HTMLVideoElement>>;
|
|
46
28
|
|
|
47
|
-
interface
|
|
29
|
+
interface ControlsProps extends React.ComponentProps<"div"> {
|
|
48
30
|
children: React.ReactNode;
|
|
49
|
-
|
|
31
|
+
asChild?: boolean;
|
|
50
32
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
declare const
|
|
63
|
-
|
|
64
|
-
declare const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
declare const useTimeline: () => {
|
|
70
|
-
currentTime: number;
|
|
71
|
-
duration: number | null;
|
|
72
|
-
buffered: number;
|
|
73
|
-
setCurrentTime: React.Dispatch<React.SetStateAction<number>>;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
declare const useGetDuration: (ref: VideoRef) => {
|
|
77
|
-
duration: number | null;
|
|
78
|
-
isLoading: boolean;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
declare const usePlayPause: (ref: VideoRef, enabled: boolean) => {
|
|
82
|
-
togglePlay: () => void;
|
|
83
|
-
isPlaying: boolean;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
declare const useMuteUnmute: (ref: VideoRef, enabled: boolean) => {
|
|
87
|
-
toggleMute: () => void;
|
|
88
|
-
isMuted: boolean;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
declare const useStartAt: (ref: VideoRef, startAt?: VideoConfig["startAt"]) => void;
|
|
92
|
-
|
|
93
|
-
declare const useFullscreen: () => {
|
|
94
|
-
isFullscreen: boolean;
|
|
95
|
-
toggleFullscreen: () => void;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
declare const useAutoplayByForce: (ref: VideoRef | null, enabled: boolean, setError?: (error: string | null) => void) => void;
|
|
99
|
-
|
|
100
|
-
declare function formatTime(time: number, type?: "h:mm:ss" | "mm:ss"): string;
|
|
101
|
-
|
|
102
|
-
export { Video, type VideoContextType, type VideoProps, formatTime, useAutoplayByForce, useFullscreen, useGetDuration, useMuteUnmute, usePlayPause, useStartAt, useTimeline, useVideo, useVolume };
|
|
33
|
+
declare const Controls: React.MemoExoticComponent<({ children, asChild, ...props }: ControlsProps) => react_jsx_runtime.JSX.Element>;
|
|
34
|
+
interface Props extends React.ComponentProps<"button"> {
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
asChild?: boolean;
|
|
37
|
+
}
|
|
38
|
+
declare const Play: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
39
|
+
declare const Pause: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
40
|
+
declare const Mute: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
41
|
+
declare const Unmute: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
42
|
+
declare const SeekForward: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
43
|
+
declare const SeekBackward: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
44
|
+
declare const Fullscreen: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
45
|
+
declare const ExitFullscreen: React.MemoExoticComponent<({ children, asChild, ...props }: Props) => react_jsx_runtime.JSX.Element>;
|
|
46
|
+
declare const Loading: () => react_jsx_runtime.JSX.Element;
|
|
47
|
+
|
|
48
|
+
export { Controls, type CustomVideoRef, ExitFullscreen, Fullscreen, Loading, Mute, Pause, Play, SeekBackward, SeekForward, Unmute, Video, type VideoAutoplay, VideoProvider, type VideoRef };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
"use client";import{
|
|
2
|
-
`);import E from"react";import g from"react";import{jsx as Q}from"react/jsx-runtime";var O=g.createContext(void 0),l=()=>{let e=g.useContext(O);if(!e)throw new Error("useVideo must be used within a VideoProvider");return e},z=({children:e,videoRef:n,duration:r,showHidingElement:t,setShowHidingElement:u})=>{let[s,o]=g.useState(!1);return Q(O.Provider,{value:{videoRef:n,duration:r,isFullscreen:s,setIsFullscreen:o,showHidingElement:t,setShowHidingElement:u},children:e})};import X from"react";var T=(e,n)=>{X.useEffect(()=>{if(!(e!=null&&e.current)||!n)return;let r=e==null?void 0:e.current;r&&n&&(r.currentTime=n)},[n,e==null?void 0:e.current])};import Y from"react";var A=(e,n,r)=>{Y.useEffect(()=>{if(!r||!(e!=null&&e.current))return;let t=new IntersectionObserver(u=>{u.forEach(s=>{var o;e!=null&&e.current&&(s.isIntersecting?e.current.play().catch(a=>{e.current&&(e.current.pause(),e.current.muted=!0,e.current.play(),console.error(a))}):(o=e.current)==null||o.pause())})},{threshold:n!=null?n:.5});return t.observe(e==null?void 0:e.current),()=>{t.disconnect()}},[r,e==null?void 0:e.current])};import L from"react";var V=(e,n)=>{let[r,t]=L.useState(!1),u=L.useCallback(()=>{console.log(e==null?void 0:e.current),e!=null&&e.current&&(e.current.paused?e.current.play():e.current.pause())},[e==null?void 0:e.current]);return L.useEffect(()=>{if(!n||!(e!=null&&e.current))return;let s=()=>{t(!0)},o=()=>{t(!1)};if(t(!(e!=null&&e.current.paused)),e!=null&&e.current)return e.current.addEventListener("play",s),e.current.addEventListener("pause",o),()=>{var a,d;(a=e.current)==null||a.removeEventListener("play",s),(d=e.current)==null||d.removeEventListener("pause",o)}},[e==null?void 0:e.current,n]),{togglePlay:u,isPlaying:r}};import{jsx as Z}from"react/jsx-runtime";var N=()=>{let{videoRef:e}=l(),{togglePlay:n}=V(e,!0);return Z("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},onClick:n})};import te from"react";import F from"react";var M=(e,n)=>{let[r,t]=F.useState(!1),u=F.useCallback(()=>{e!=null&&e.current&&(e.current.muted=!e.current.muted)},[e==null?void 0:e.current]);return F.useEffect(()=>{if(!n||!(e!=null&&e.current))return;t(e.current.muted);let s=()=>{e.current&&t(e.current.muted)};return e.current.addEventListener("volumechange",s),()=>{var o;(o=e.current)==null||o.removeEventListener("volumechange",s)}},[e==null?void 0:e.current,n]),{toggleMute:u,isMuted:r}};import _ from"react";var w=()=>{let{videoRef:e,isFullscreen:n,setIsFullscreen:r}=l();_.useEffect(()=>{let u=()=>{r==null||r(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",u),()=>document.removeEventListener("fullscreenchange",u)},[]);let t=()=>{var a;let u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),s=e==null?void 0:e.current;if(s&&u){if(s.webkitEnterFullscreen){s.webkitEnterFullscreen();return}else if(s.requestFullscreen){s.requestFullscreen();return}}let o=(a=e==null?void 0:e.current)==null?void 0:a.closest("[data-zuude-video-wrapper]");o&&(n?document.exitFullscreen():o.requestFullscreen())};return{isFullscreen:n!=null?n:!1,toggleFullscreen:t}};import ee from"react";var q=()=>{let{videoRef:e,isPictureInPicture:n,setIsPictureInPicture:r}=l();ee.useEffect(()=>{let u=()=>{r==null||r(!!document.pictureInPictureElement)};return document.addEventListener("pictureinpicturechange",u),()=>document.removeEventListener("pictureinpicturechange",u)},[]);let t=async()=>{let u=e==null?void 0:e.current;if(u)try{document.pictureInPictureElement?await document.exitPictureInPicture():await u.requestPictureInPicture()}catch(s){if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent))u.webkitEnterFullscreen?u.webkitEnterFullscreen():u.requestFullscreen&&u.requestFullscreen();else{let a=u.closest("[data-zuude-video-wrapper]");a&&(document.fullscreenElement?await document.exitFullscreen():await a.requestFullscreen())}}};return{isPictureInPicture:n!=null?n:!1,togglePictureInPicture:t}};import S from"react";var $=(e,n)=>{let[r,t]=S.useState(1),u=s=>{t(s)};return S.useEffect(()=>{e!=null&&e.current&&t(e.current.playbackRate)},[e==null?void 0:e.current]),S.useEffect(()=>{!n||!(e!=null&&e.current)||(e.current.playbackRate=r)},[r,n,e==null?void 0:e.current]),{speed:r,onChangeSpeed:u}};var B=te.forwardRef(({children:e},n)=>{let{duration:r,showHidingElement:t}=l(),{togglePlay:u,isPlaying:s}=V(n,typeof e=="function"),{speed:o,onChangeSpeed:a}=$(n,typeof e=="function"),{toggleMute:d,isMuted:m}=M(n,typeof e=="function"),{isFullscreen:v,toggleFullscreen:b}=w(),{isPictureInPicture:x,togglePictureInPicture:i}=q();return typeof e!="function"?null:e({isPlaying:s,togglePlay:u,isMuted:m,toggleMute:d,speed:o,onChangeSpeed:a,isFullscreen:v,toggleFullscreen:b,isPictureInPicture:x,togglePictureInPicture:i,duration:r,showHidingElement:t!=null?t:!1})});import re from"react";import{jsx as ne}from"react/jsx-runtime";var D=re.forwardRef(({children:e,className:n,...r})=>{let{videoRef:t}=l(),{isPlaying:u}=V(t,!0),{showHidingElement:s,setShowHidingElement:o}=l();return ne("div",{"data-zuude-hiding-element":!0,"data-show":!u||s,className:n,onMouseEnter:()=>{o==null||o(!0)},onMouseLeave:()=>{o==null||o(!1)},...r,children:e})});import{jsx as I,jsxs as ue}from"react/jsx-runtime";var U=E.forwardRef(({children:e,autoPlay:n,className:r,config:t,ratio:u,controls:s,pause:o,...a},d)=>{let[m,v]=E.useState(null),[b,x]=E.useState(null),i=d||E.useRef(null),[j,h]=E.useState(!1),y=E.useRef(null),G=()=>{var c;(c=i.current)!=null&&c.paused||(h(!0),y.current&&clearTimeout(y.current))},W=()=>{var c;(c=i.current)!=null&&c.paused||(h(!1),y.current&&clearTimeout(y.current))},J=()=>{var c;(c=i.current)!=null&&c.paused||(h(!0),y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{h(!1)},3e3))};return E.useEffect(()=>{var c,p;o!==void 0&&(o?(c=i.current)==null||c.pause():(p=i.current)==null||p.play())},[o,i.current]),C(i,n==="force"&&a.muted===void 0&&!(t!=null&&t.autoplayOnVisible),x),T(i,t==null?void 0:t.startAt),A(i,typeof(t==null?void 0:t.autoplayOnVisible)=="number"?t.autoplayOnVisible:void 0,t==null?void 0:t.autoplayOnVisible),I(z,{videoRef:i,duration:m,showHidingElement:j,setShowHidingElement:h,children:ue("div",{"data-zuude-video-wrapper":!0,className:r,style:{aspectRatio:u},children:[I("video",{"data-zuude-video":!0,ref:i,autoPlay:t!=null&&t.autoplayOnVisible?!1:n==="force"?!0:n,playsInline:!0,onMouseEnter:G,onMouseLeave:W,onMouseMove:J,onClick:()=>{var c,p,P;t!=null&&t.clickToPlay&&((c=i.current)!=null&&c.paused?(p=i.current)==null||p.play():(P=i.current)==null||P.pause())},onLoadedMetadata:c=>{console.log("loaded metadata"),v(c.target.duration)},onTimeUpdate:c=>{var p;if(t!=null&&t.range){let[P,K]=t.range;if(!(i!=null&&i.current))return;((p=i==null?void 0:i.current)==null?void 0:p.currentTime)<P&&(i.current.currentTime=P),i.current.currentTime>K&&(i.current.currentTime=P)}},className:r,style:{aspectRatio:u},...a}),typeof e=="function"?I(B,{ref:i,children:e}):e,b==="NotAllowedError"&&typeof(t==null?void 0:t.muteFallback)=="function"&&t.muteFallback(()=>{i.current&&(i.current.muted=!i.current.muted),x(null)})]})})});U.displayName="Video";var oe=Object.assign(U,{PlayPauseOnVideo:N,HidingElement:D});import H from"react";var se=()=>{let[e,n]=H.useState(100),{videoRef:r}=l(),t=u=>{n(u)};return H.useEffect(()=>{r!=null&&r.current&&n(r.current.volume*100)},[r==null?void 0:r.current]),H.useEffect(()=>{r!=null&&r.current&&(r.current.volume=e/100)},[e,r==null?void 0:r.current]),{volume:e,onChangeVolume:t}};import f from"react";var ie=()=>{let[e,n]=f.useState(!1),[r,t]=f.useState(0),[u,s]=f.useState(0),{videoRef:o,duration:a}=l();return f.useEffect(()=>{if(o!=null&&o.current&&e){let d=setInterval(()=>{var m,v;t(((m=o.current)==null?void 0:m.currentTime)||0),(v=o.current)!=null&&v.buffered.length&&s(o.current.buffered.end(o.current.buffered.length-1))},10);return()=>clearInterval(d)}},[o==null?void 0:o.current,e]),f.useEffect(()=>{if(o!=null&&o.current)return o.current.addEventListener("play",()=>n(!0)),o.current.addEventListener("pause",()=>n(!1)),()=>{var d,m;(d=o.current)==null||d.removeEventListener("play",()=>n(!0)),(m=o.current)==null||m.removeEventListener("pause",()=>n(!1))}},[]),{currentTime:r,duration:a,buffered:u,setCurrentTime:t}};import k from"react";var ae=e=>{let[n,r]=k.useState(!1),[t,u]=k.useState(null);return k.useEffect(()=>{if(e!=null&&e.current)return r(!0),e.current.addEventListener("loadedmetadata",()=>{var s,o;u((o=(s=e.current)==null?void 0:s.duration)!=null?o:null),r(!1)}),e.current.addEventListener("error",()=>{r(!1)}),()=>{var s,o;(s=e.current)==null||s.removeEventListener("loadedmetadata",()=>{}),(o=e.current)==null||o.removeEventListener("error",()=>{})}},[e==null?void 0:e.current]),{duration:t,isLoading:n}};function ce(e,n="mm:ss"){let r=Math.floor(e/60),t=Math.floor(e%60);return n==="h:mm:ss"?`${Math.floor(r/60)}:${r}:${t<10?"0":""}${t}`:`${r}:${t<10?"0":""}${t}`}export{oe as Video,ce as formatTime,C as useAutoplayByForce,w as useFullscreen,ae as useGetDuration,M as useMuteUnmute,V as usePlayPause,T as useStartAt,ie as useTimeline,l as useVideo,se as useVolume};
|
|
1
|
+
"use client";import J,{createContext as Q,useContext as X,useEffect as A,useRef as Y,useState as I}from"react";import{jsx as N}from"react/jsx-runtime";var j=Q(null),Z=J.memo(({children:t,config:n,onError:r,...o})=>{let[e,s]=I({current:null}),[u,a]=I(null),[d,P]=I(!1),C=Y(null);return A(()=>{r==null||r(u)},[u]),A(()=>{let l=C.current;if(l){let p=l.querySelectorAll("[data-zuude-hide-elements]"),m=l.querySelector("[data-zuude-video]");if(p){let c=null,h=3e3,g=!1,H=()=>{c&&(clearTimeout(c),c=null),c=setTimeout(()=>{g&&m&&!m.paused&&p.forEach(y=>{y.setAttribute("data-hidden","true")}),c=null},h)},f=()=>{g=!0,p.forEach(y=>{y.removeAttribute("data-hidden")}),H()},S=()=>{g=!1,c&&(clearTimeout(c),c=null),m&&!m.paused&&p.forEach(y=>{y.setAttribute("data-hidden","true")})},q=()=>{g&&(p.forEach(y=>{y.hasAttribute("data-hidden")&&y.removeAttribute("data-hidden")}),H())},O=()=>{g||p.forEach(y=>{y.setAttribute("data-hidden","true")})};return l.addEventListener("mouseenter",f),l.addEventListener("mouseleave",S),l.addEventListener("mousemove",q),m.addEventListener("pause",f),m.addEventListener("play",O),()=>{c&&clearTimeout(c),l.removeEventListener("mouseenter",f),l.removeEventListener("mouseleave",S),l.removeEventListener("mousemove",q),m.removeEventListener("pause",f),m.removeEventListener("play",O)}}}},[]),A(()=>{if(d){let l=p=>{var m;(m=C.current)!=null&&m.contains(p.target)||P(!1)};return document.addEventListener("click",l),()=>{document.removeEventListener("click",l)}}},[d]),N(j.Provider,{value:{videoRef:e,setVideoRef:s,config:{clickToPlay:!0,...n},error:u,setError:a,isFocused:d,setIsFocused:P},children:N("div",{ref:C,"data-zuude-video-wrapper":!0,onClick:()=>P(!0),...o,children:t})})}),i=()=>{let t=X(j);if(!t)throw new Error("useVideo must be used within a VideoProvider");return t};import{forwardRef as v,useEffect as R,useRef as tt}from"react";import _ from"react";var z=(t,n,r)=>{_.useEffect(()=>{if(!(t!=null&&t.current)||!n)return;(async()=>{var e;try{await((e=t.current)==null?void 0:e.play())}catch(s){if(s instanceof Error&&s.name==="NotAllowedError"){if(r==null||r("NotAllowedError"),console.error("NotAllowedError"),t!=null&&t.current){t.current.muted=!0;try{await t.current.play()}catch(u){console.error(u)}}}else console.error(s)}})()},[n,t==null?void 0:t.current])};import{useEffect as $}from"react";var k=(t,n,r=!0)=>{let o=e=>{e.key===t&&(e.preventDefault(),n(e))};$(()=>{if(r)return document.addEventListener("keydown",o),()=>{document.removeEventListener("keydown",o)}},[t,n,r])};import K from"react";var L=(t,n=10)=>{let r=K.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime+=n)},[t==null?void 0:t.current]),o=K.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime-=n)},[t==null?void 0:t.current]);return{seekForward:r,seekBackward:o}};import w from"react";var F=t=>{let[n,r]=w.useState(!1),o=w.useCallback(()=>{t!=null&&t.current&&(t.current.paused?t.current.play():t.current.pause())},[t==null?void 0:t.current]),e=w.useCallback(()=>{t!=null&&t.current&&t.current.play()},[t==null?void 0:t.current]),s=w.useCallback(()=>{t!=null&&t.current&&t.current.pause()},[t==null?void 0:t.current]);return w.useEffect(()=>{if(!(t!=null&&t.current))return;let u=()=>{r(!0)},a=()=>{r(!1)};if(r(!(t!=null&&t.current.paused)),t!=null&&t.current)return t.current.addEventListener("play",u),t.current.addEventListener("pause",a),()=>{var d,P;(d=t.current)==null||d.removeEventListener("play",u),(P=t.current)==null||P.removeEventListener("pause",a)}},[t==null?void 0:t.current]),{togglePlay:o,isPlaying:n,play:e,pause:s}};import x from"react";var T=t=>{let[n,r]=x.useState(!1),o=x.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!t.current.muted)},[t==null?void 0:t.current]),e=x.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!0)},[t==null?void 0:t.current]),s=x.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!1)},[t==null?void 0:t.current]);return x.useEffect(()=>{if(!(t!=null&&t.current))return;r(t.current.muted);let u=()=>{t.current&&r(t.current.muted)};return t.current.addEventListener("volumechange",u),()=>{var a;(a=t.current)==null||a.removeEventListener("volumechange",u)}},[t==null?void 0:t.current]),{toggleMute:o,isMuted:n,mute:e,unmute:s}};import B from"react";var M=t=>{let[n,r]=B.useState(!1);B.useEffect(()=>{let e=()=>{r==null||r(!!document.fullscreenElement),o()};return document.addEventListener("fullscreenchange",e),()=>document.removeEventListener("fullscreenchange",e)},[n]);let o=()=>{console.log("toggleFullscreen");let e=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),s=t==null?void 0:t.current;if(s&&e){if(s.webkitEnterFullscreen){s.webkitEnterFullscreen();return}else if(s.requestFullscreen){s.requestFullscreen();return}}let u=s==null?void 0:s.closest("[data-zuude-video-wrapper]");u&&(n?(document.exitFullscreen(),s&&(s.style.objectFit="cover")):(u.requestFullscreen(),s&&(s.style.objectFit="contain")))};return{isFullscreen:n!=null?n:!1,toggleFullscreen:o}};var D=t=>({togglePictureInPicture:async()=>{let e=t==null?void 0:t.current;if(e)try{document.pictureInPictureElement?await document.exitPictureInPicture():await e.requestPictureInPicture()}catch(s){if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent))e.webkitEnterFullscreen?e.webkitEnterFullscreen():e.requestFullscreen&&e.requestFullscreen();else{let a=e.closest("[data-zuude-video-wrapper]");a&&(document.fullscreenElement?await document.exitFullscreen():await a.requestFullscreen())}}},requestPictureInPicture:async()=>{let e=t==null?void 0:t.current;e&&await e.requestPictureInPicture()},exitPictureInPicture:async()=>{t!=null&&t.current&&await document.exitPictureInPicture()}});var U=()=>{let{videoRef:t}=i(),{seekForward:n,seekBackward:r}=L(t),{togglePlay:o}=F(t),{toggleMute:e}=T(t),{toggleFullscreen:s}=M(t),{togglePictureInPicture:u}=D(t);return k("ArrowRight",()=>{n()}),k("ArrowLeft",()=>{r()}),k(" ",()=>{o()}),k("m",()=>{e()}),k("f",()=>{s()}),k("p",()=>{u()}),null};import{Fragment as et,jsx as W,jsxs as rt}from"react/jsx-runtime";var G=v(({src:t,autoPlay:n,muteFallback:r,controls:o,...e},s)=>{let{videoRef:u,setVideoRef:a,config:d,setError:P,error:C,isFocused:l}=i(),p=tt(null);R(()=>{let c=p.current,h=s;h?a(h):c&&a({current:c})},[t]),z(u,n==="force"&&e.muted===void 0,P);let m=()=>{var c,h,g;(c=u==null?void 0:u.current)!=null&&c.paused?(h=u.current)==null||h.play():(g=u==null?void 0:u.current)==null||g.pause()};return rt(et,{children:[W("video",{ref:s||p,"data-zuude-video":!0,src:t,onClick:d!=null&&d.clickToPlay?m:void 0,autoPlay:n==="force"?!0:n,...e}),o&&l&&W(U,{}),C==="NotAllowedError"&&typeof r=="function"&&r(()=>{u!=null&&u.current&&(u.current.muted=!u.current.muted),P(null)})]})});G.displayName="Video";import V from"react";import{Slot as b}from"@radix-ui/react-slot";import{jsx as E}from"react/jsx-runtime";var Wt=V.memo(({children:t,asChild:n,...r})=>E("div",{"data-zuude-hide-elements":!0,...r,children:t})),Gt=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{play:s}=F(e);return E(o,{...r,onClick:s,children:t})}),Jt=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{pause:s}=F(e);return E(o,{...r,onClick:s,children:t})}),Qt=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{mute:s}=T(e);return E(o,{...r,onClick:s,children:t})}),Xt=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{unmute:s}=T(e);return E(o,{...r,onClick:s,children:t})}),Yt=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{seekForward:s}=L(e,10);return E(o,{...r,onClick:s,children:t})}),Zt=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{seekBackward:s}=L(e,10);return E(o,{...r,onClick:s,children:t})}),_t=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{toggleFullscreen:s}=M(e);return E(o,{...r,onClick:s,children:t})}),$t=V.memo(({children:t,asChild:n,...r})=>{let o=n?b:"button",{videoRef:e}=i(),{toggleFullscreen:s}=M(e);return E(o,{...r,onClick:s,children:t})}),vt=()=>E("div",{children:"Loading"});export{Wt as Controls,$t as ExitFullscreen,_t as Fullscreen,vt as Loading,Qt as Mute,Jt as Pause,Gt as Play,Zt as SeekBackward,Yt as SeekForward,Xt as Unmute,G as Video,Z as VideoProvider};
|
|
3
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["#style-inject:#style-inject","../src/styles.css","../src/video.tsx","../src/context.tsx","../src/hooks/use-start-at.tsx","../src/hooks/use-autoplay-on-visible.tsx","../src/hooks/use-play-pause.tsx","../src/components/play-pause-on-video.tsx","../src/function-children.tsx","../src/hooks/use-mute-unmute.tsx","../src/hooks/use-fullscreen.tsx","../src/hooks/use-picture-in-picture.tsx","../src/hooks/use-speed.tsx","../src/components/hiding-element.tsx","../src/hooks/use-volume.tsx","../src/hooks/use-timeline.tsx","../src/hooks/use-get-duration.tsx","../src/utils.ts"],"sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".reset-styles{box-sizing:border-box;padding:0;margin:0}[data-zuude-video-wrapper]{position:relative}[data-zuude-video-wrapper] [data-zuude-video]{width:100%;height:100%;object-fit:cover}\\n\")","import React from \"react\";\n\n// 📦 Types\nimport type { VideoProps, VideoRef } from \"./types\";\n\n// 🔍 Context\nimport { VideoProvider } from \"./context\";\n\n// 🔗 Hooks\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { useStartAt } from \"./hooks/use-start-at\";\nimport { useAutoplayOnVisible } from \"./hooks/use-autoplay-on-visible\";\n\n// 🔧 Components\nimport { PlayPauseOnVideo } from \"./components/play-pause-on-video\";\nimport { FunctionChildren } from \"./function-children\";\nimport { HidingElement, HidingElementProps } from \"./components/hiding-element\";\n\n/**\n * Main Video component structure\n * @param {VideoProps} props - Video component props\n */\n\nconst VideoComponent = React.forwardRef<\n HTMLVideoElement,\n VideoProps & { pause?: boolean }\n>(\n (\n { children, autoPlay, className, config, ratio, controls, pause, ...props },\n ref\n ) => {\n const [duration, setDuration] = React.useState<number | null>(null);\n const [error, setError] = React.useState<string | null>(null);\n\n const videoRef = (ref as VideoRef) || React.useRef<VideoRef>(null);\n\n const [showHidingElement, setShowHidingElement] = React.useState(false);\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout>>(null);\n const handleMouseEnter = () => {\n if (videoRef.current?.paused) return;\n\n setShowHidingElement(true);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n const handleMouseLeave = () => {\n if (videoRef.current?.paused) return;\n\n setShowHidingElement(false);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n const handleMouseMove = () => {\n if (videoRef.current?.paused) return;\n\n setShowHidingElement(true);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => {\n setShowHidingElement(false);\n }, 3000);\n };\n\n React.useEffect(() => {\n if (pause !== undefined) {\n if (pause) {\n videoRef.current?.pause();\n } else {\n videoRef.current?.play();\n }\n }\n }, [pause, videoRef.current]);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" &&\n props.muted === undefined &&\n !config?.autoplayOnVisible,\n setError\n );\n useStartAt(videoRef, config?.startAt);\n useAutoplayOnVisible(\n videoRef,\n typeof config?.autoplayOnVisible === \"number\"\n ? config.autoplayOnVisible\n : undefined,\n config?.autoplayOnVisible\n );\n\n return (\n <VideoProvider\n videoRef={videoRef}\n duration={duration}\n showHidingElement={showHidingElement}\n setShowHidingElement={setShowHidingElement}\n >\n <div\n data-zuude-video-wrapper\n className={className}\n style={{ aspectRatio: ratio }}\n >\n <video\n data-zuude-video\n // @ts-ignore\n ref={videoRef}\n autoPlay={\n config?.autoplayOnVisible\n ? false\n : autoPlay === \"force\"\n ? true\n : autoPlay\n }\n playsInline\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onMouseMove={handleMouseMove}\n onClick={() => {\n if (config?.clickToPlay) {\n if (videoRef.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef.current?.pause();\n }\n }\n }}\n onLoadedMetadata={(e) => {\n console.log(\"loaded metadata\");\n setDuration((e.target as HTMLVideoElement).duration);\n }}\n onTimeUpdate={(e) => {\n /**\n * If the current time is less than the start time, set the current time to the start time\n * If the current time is greater than the end time, set the current time to the start time\n */\n if (config?.range) {\n const [start, end] = config.range;\n\n if (!videoRef?.current) return;\n\n if (videoRef?.current?.currentTime < start) {\n videoRef.current.currentTime = start;\n }\n\n if (videoRef.current.currentTime > end) {\n videoRef.current.currentTime = start;\n }\n }\n }}\n className={className}\n style={{ aspectRatio: ratio }}\n {...props}\n />\n {typeof children === \"function\" ? (\n <FunctionChildren ref={videoRef} children={children} />\n ) : (\n children\n )}\n {error === \"NotAllowedError\" &&\n typeof config?.muteFallback === \"function\" &&\n config.muteFallback(() => {\n if (videoRef.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </div>\n </VideoProvider>\n );\n }\n);\n\nVideoComponent.displayName = \"Video\";\n\n/**\n * Using compound components pattern\n */\nexport const Video = Object.assign(VideoComponent, {\n PlayPauseOnVideo,\n HidingElement: HidingElement as React.ComponentType<HidingElementProps>,\n});\n","import React from \"react\";\nimport type { VideoContextType } from \"./types.js\";\n\nconst VideoContext = React.createContext<VideoContextType | undefined>(\n undefined\n);\n\nconst useVideo = () => {\n const context = React.useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n\ninterface VideoProviderProps extends VideoContextType {\n children: React.ReactNode;\n}\n\nconst VideoProvider = ({\n children,\n videoRef,\n duration,\n showHidingElement,\n setShowHidingElement,\n}: VideoProviderProps) => {\n const [fullscreen, setFullscreen] = React.useState(false);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n duration,\n isFullscreen: fullscreen,\n setIsFullscreen: setFullscreen,\n showHidingElement,\n setShowHidingElement,\n }}\n >\n {children}\n </VideoContext.Provider>\n );\n};\n\nexport { useVideo, VideoProvider };\n","import React from \"react\";\nimport type { VideoConfig, VideoRef } from \"../types\";\n\nexport const useStartAt = (ref: VideoRef, startAt?: VideoConfig[\"startAt\"]) => {\n React.useEffect(() => {\n if (!ref?.current || !startAt) return;\n\n const video = ref?.current;\n if (video && startAt) {\n video.currentTime = startAt;\n }\n }, [startAt, ref?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayOnVisible = (\n ref: VideoRef,\n threshold: number | undefined,\n enabled: boolean | number | null | undefined\n) => {\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (!ref?.current) return;\n\n if (entry.isIntersecting) {\n ref.current.play().catch((error) => {\n if (!ref.current) return;\n\n ref.current.pause();\n ref.current.muted = true;\n ref.current.play();\n console.error(error);\n });\n } else {\n ref.current?.pause();\n }\n });\n },\n { threshold: threshold ?? 0.5 }\n );\n\n observer.observe(ref?.current);\n\n return () => {\n observer.disconnect();\n };\n }, [enabled, ref?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const usePlayPause = (ref: VideoRef, enabled: boolean) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n\n const togglePlay = React.useCallback(() => {\n console.log(ref?.current);\n if (ref?.current) {\n ref.current.paused ? ref.current.play() : ref.current.pause();\n }\n }, [ref?.current]);\n\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n const handlePlay = () => {\n setIsPlaying(true);\n };\n const handlePause = () => {\n setIsPlaying(false);\n };\n\n setIsPlaying(!ref?.current.paused);\n\n if (ref?.current) {\n ref.current.addEventListener(\"play\", handlePlay);\n ref.current.addEventListener(\"pause\", handlePause);\n\n return () => {\n ref.current?.removeEventListener(\"play\", handlePlay);\n ref.current?.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [ref?.current, enabled]);\n\n return { togglePlay, isPlaying };\n};\n","import { useVideo } from \"../context\";\nimport { usePlayPause } from \"../hooks/use-play-pause\";\n\nexport const PlayPauseOnVideo = () => {\n const { videoRef } = useVideo();\n\n const { togglePlay } = usePlayPause(videoRef, true);\n\n return (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n onClick={togglePlay}\n ></div>\n );\n};\n","import React from \"react\";\n\nimport type { VideoChildren, VideoRef } from \"./types\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useVideo } from \"./context\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\nimport { useSpeed } from \"./hooks/use-speed\";\n\nexport const FunctionChildren = React.forwardRef<\n any,\n {\n children: VideoChildren;\n }\n>(({ children }, ref) => {\n const { duration, showHidingElement } = useVideo();\n\n /**\n * Only use these hooks if the children is a function\n */\n const { togglePlay, isPlaying } = usePlayPause(\n ref as VideoRef,\n typeof children === \"function\"\n );\n const { speed, onChangeSpeed } = useSpeed(\n ref as VideoRef,\n typeof children === \"function\"\n );\n const { toggleMute, isMuted } = useMuteUnmute(\n ref as VideoRef,\n typeof children === \"function\"\n );\n const { isFullscreen, toggleFullscreen } = useFullscreen();\n const { isPictureInPicture, togglePictureInPicture } = usePictureInPicture();\n\n if (typeof children !== \"function\") return null;\n\n return children({\n isPlaying,\n togglePlay,\n isMuted,\n toggleMute,\n speed,\n onChangeSpeed,\n isFullscreen,\n toggleFullscreen,\n isPictureInPicture,\n togglePictureInPicture,\n duration,\n showHidingElement: showHidingElement ?? false,\n });\n});\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useMuteUnmute = (ref: VideoRef, enabled: boolean) => {\n const [isMuted, setIsMuted] = React.useState(false);\n\n const toggleMute = React.useCallback(() => {\n if (ref?.current) {\n ref.current.muted = !ref.current.muted;\n }\n }, [ref?.current]);\n\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n // Set the initial state\n setIsMuted(ref.current.muted);\n\n const handleVolumeChange = () => {\n if (ref.current) {\n setIsMuted(ref.current.muted);\n }\n };\n\n ref.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n ref.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [ref?.current, enabled]);\n\n return { toggleMute, isMuted };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const useFullscreen = () => {\n const { videoRef, isFullscreen, setIsFullscreen } = useVideo();\n\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen?.(!!document.fullscreenElement);\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, []);\n\n const toggleFullscreen = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const video = videoRef?.current;\n\n if (video && isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n return;\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n return;\n }\n }\n\n const videoContainer = videoRef?.current?.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n\n if (videoContainer) {\n if (!isFullscreen) {\n videoContainer.requestFullscreen();\n } else {\n document.exitFullscreen();\n }\n }\n };\n\n return { isFullscreen: isFullscreen ?? false, toggleFullscreen };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const usePictureInPicture = () => {\n const { videoRef, isPictureInPicture, setIsPictureInPicture } = useVideo();\n\n React.useEffect(() => {\n const handlePictureInPictureChange = () => {\n setIsPictureInPicture?.(!!document.pictureInPictureElement);\n };\n\n document.addEventListener(\n \"pictureinpicturechange\",\n handlePictureInPictureChange\n );\n return () =>\n document.removeEventListener(\n \"pictureinpicturechange\",\n handlePictureInPictureChange\n );\n }, []);\n\n const togglePictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await video.requestPictureInPicture();\n }\n } catch (error) {\n // Fallback for browsers that don't support PiP\n const isSafari = /^((?!chrome|android).)*safari/i.test(\n navigator.userAgent\n );\n\n if (isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n }\n } else {\n const videoContainer = video.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n if (videoContainer) {\n if (!document.fullscreenElement) {\n await videoContainer.requestFullscreen();\n } else {\n await document.exitFullscreen();\n }\n }\n }\n }\n };\n\n return {\n isPictureInPicture: isPictureInPicture ?? false,\n togglePictureInPicture,\n };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSpeed = (ref: VideoRef, enabled: boolean) => {\n const [speed, setSpeed] = React.useState(1);\n\n const onChangeSpeed = (speed: number) => {\n setSpeed(speed);\n };\n\n // Get the speed from the video element\n React.useEffect(() => {\n if (!ref?.current) return;\n setSpeed(ref.current.playbackRate);\n }, [ref?.current]);\n\n React.useEffect(() => {\n if (!enabled || !ref?.current) return;\n\n ref.current.playbackRate = speed;\n }, [speed, enabled, ref?.current]);\n\n return { speed, onChangeSpeed };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\nimport { usePlayPause } from \"../hooks/use-play-pause\";\n\nexport interface HidingElementProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n children: React.ReactNode;\n className?: string;\n}\n\nexport const HidingElement = React.forwardRef<\n HTMLDivElement,\n HidingElementProps\n>(({ children, className, ...props }: HidingElementProps) => {\n const { videoRef } = useVideo();\n const { isPlaying } = usePlayPause(videoRef, true);\n const { showHidingElement, setShowHidingElement } = useVideo();\n\n return (\n <div\n data-zuude-hiding-element\n data-show={!isPlaying || showHidingElement}\n className={className}\n onMouseEnter={() => {\n setShowHidingElement?.(true);\n }}\n onMouseLeave={() => {\n setShowHidingElement?.(false);\n }}\n {...props}\n >\n {children}\n </div>\n );\n});\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const useVolume = () => {\n const [volume, setVolume] = React.useState(100);\n const { videoRef } = useVideo();\n\n const onChangeVolume = (volume: number) => {\n setVolume(volume);\n };\n\n // Get the volume from the video element\n React.useEffect(() => {\n if (!videoRef?.current) return;\n setVolume(videoRef.current.volume * 100);\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.volume = volume / 100;\n }, [volume, videoRef?.current]);\n\n return { volume, onChangeVolume };\n};\n","import React from \"react\";\nimport { useVideo } from \"../context\";\n\nexport const useTimeline = () => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n const [buffered, setBuffered] = React.useState(0);\n\n const { videoRef, duration } = useVideo();\n\n React.useEffect(() => {\n if (videoRef?.current && isPlaying) {\n const intervalId = setInterval(() => {\n setCurrentTime(videoRef.current?.currentTime || 0);\n\n if (videoRef.current?.buffered.length) {\n setBuffered(\n videoRef.current.buffered.end(videoRef.current.buffered.length - 1)\n );\n }\n }, 10);\n\n return () => clearInterval(intervalId);\n }\n }, [videoRef?.current, isPlaying]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.addEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current.addEventListener(\"pause\", () => setIsPlaying(false));\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current?.removeEventListener(\"pause\", () => setIsPlaying(false));\n };\n }, []);\n\n return {\n currentTime,\n duration,\n buffered,\n setCurrentTime,\n };\n};\n","import React from \"react\";\nimport { VideoRef } from \"../types.js\";\n\nexport const useGetDuration = (ref: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n const [duration, setDuration] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!ref?.current) return;\n setIsLoading(true);\n\n ref.current.addEventListener(\"loadedmetadata\", () => {\n setDuration(ref.current?.duration ?? null);\n setIsLoading(false);\n });\n\n ref.current.addEventListener(\"error\", () => {\n setIsLoading(false);\n });\n\n return () => {\n ref.current?.removeEventListener(\"loadedmetadata\", () => {});\n ref.current?.removeEventListener(\"error\", () => {});\n };\n }, [ref?.current]);\n\n return { duration, isLoading };\n};\n","function formatTime(time: number, type: \"h:mm:ss\" | \"mm:ss\" = \"mm:ss\"): string {\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n if (type === \"h:mm:ss\") {\n const hours = Math.floor(minutes / 60);\n return `${hours}:${minutes}:${seconds < 10 ? \"0\" : \"\"}${seconds}`;\n }\n return `${minutes}:${seconds < 10 ? \"0\" : \"\"}${seconds}`;\n}\n\nexport { formatTime };\n"],"mappings":"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","names":["styleInject","css","insertAt","head","style","styleInject","React","React","jsx","VideoContext","useVideo","context","VideoProvider","children","videoRef","duration","showHidingElement","setShowHidingElement","fullscreen","setFullscreen","React","useStartAt","ref","startAt","video","React","useAutoplayOnVisible","ref","threshold","enabled","observer","entries","entry","_a","error","React","usePlayPause","ref","enabled","isPlaying","setIsPlaying","togglePlay","handlePlay","handlePause","_a","_b","jsx","PlayPauseOnVideo","videoRef","useVideo","togglePlay","usePlayPause","React","React","useMuteUnmute","ref","enabled","isMuted","setIsMuted","toggleMute","handleVolumeChange","_a","React","useFullscreen","videoRef","isFullscreen","setIsFullscreen","useVideo","React","handleFullscreenChange","toggleFullscreen","_a","isSafari","video","videoContainer","React","usePictureInPicture","videoRef","isPictureInPicture","setIsPictureInPicture","useVideo","React","handlePictureInPictureChange","togglePictureInPicture","video","error","videoContainer","React","useSpeed","ref","enabled","speed","setSpeed","onChangeSpeed","FunctionChildren","React","children","ref","duration","showHidingElement","useVideo","togglePlay","isPlaying","usePlayPause","speed","onChangeSpeed","useSpeed","toggleMute","isMuted","useMuteUnmute","isFullscreen","toggleFullscreen","useFullscreen","isPictureInPicture","togglePictureInPicture","usePictureInPicture","React","jsx","HidingElement","React","children","className","props","videoRef","useVideo","isPlaying","usePlayPause","showHidingElement","setShowHidingElement","jsx","jsxs","VideoComponent","React","children","autoPlay","className","config","ratio","controls","pause","props","ref","duration","setDuration","error","setError","videoRef","showHidingElement","setShowHidingElement","timeoutRef","handleMouseEnter","_a","handleMouseLeave","handleMouseMove","_b","useAutoplayByForce","useStartAt","useAutoplayOnVisible","VideoProvider","_c","e","start","end","FunctionChildren","Video","PlayPauseOnVideo","HidingElement","React","useVolume","volume","setVolume","React","videoRef","useVideo","onChangeVolume","React","useTimeline","isPlaying","setIsPlaying","React","currentTime","setCurrentTime","buffered","setBuffered","videoRef","duration","useVideo","intervalId","_a","_b","React","useGetDuration","ref","isLoading","setIsLoading","duration","setDuration","_a","_b","formatTime","time","type","minutes","seconds"]}
|
|
1
|
+
{"version":3,"sources":["../src/wrapper.tsx","../src/video.tsx","../src/hooks/use-autoplay-by-force.tsx","../src/hooks/use-hot-keys.tsx","../src/hooks/use-seek.tsx","../src/hooks/use-play-pause.tsx","../src/hooks/use-mute-unmute.tsx","../src/hooks/use-fullscreen.tsx","../src/hooks/use-picture-in-picture.tsx","../src/keyboard.tsx","../src/components.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { VideoRef } from \"./types\";\n\ninterface VideoConfig {\n config?: Partial<{\n clickToPlay: boolean;\n }>;\n}\n\ninterface VideoContextType extends VideoConfig {\n videoRef: VideoRef;\n setVideoRef: (video: VideoRef) => void;\n error: string | null;\n setError: (error: string | null) => void;\n isFocused: boolean;\n setIsFocused: (isFocused: boolean) => void;\n}\n\nexport const VideoContext = createContext<VideoContextType | null>(null);\n\ntype VideoProviderProps = Omit<React.ComponentProps<\"div\">, \"onError\"> &\n VideoConfig & {\n children: React.ReactNode;\n onError?: (error: string | null) => void;\n };\n\nexport const VideoProvider = React.memo(\n ({ children, config, onError, ...props }: VideoProviderProps) => {\n const [videoRef, setVideoRef] = useState<VideoRef>({ current: null });\n const [error, setError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n const videoWrapperRef = useRef<HTMLDivElement>(null);\n\n // Sending error to user if it exists\n useEffect(() => {\n onError?.(error);\n }, [error]);\n\n useEffect(() => {\n const videoWrapper = videoWrapperRef.current;\n if (videoWrapper) {\n const controls = videoWrapper.querySelectorAll(\n \"[data-zuude-hide-elements]\"\n );\n const video = videoWrapper.querySelector(\n \"[data-zuude-video]\"\n ) as HTMLVideoElement;\n\n if (controls) {\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n const hideDelay = 3000; // 3 seconds delay\n let isMouseOver = false;\n\n const resetTimer = () => {\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n\n // Start new timer to hide controls after delay\n hideTimeout = setTimeout(() => {\n if (isMouseOver) {\n // Check if video is paused - don't hide controls if paused\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n }\n hideTimeout = null;\n }, hideDelay);\n };\n\n const showControls = () => {\n isMouseOver = true;\n controls.forEach((control) => {\n control.removeAttribute(\"data-hidden\");\n });\n resetTimer();\n };\n\n const hideControls = () => {\n isMouseOver = false;\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n // Hide controls immediately when mouse leaves\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n const handleMouseMove = () => {\n if (isMouseOver) {\n // If controls are hidden, show them\n controls.forEach((control) => {\n if (control.hasAttribute(\"data-hidden\")) {\n control.removeAttribute(\"data-hidden\");\n }\n });\n resetTimer();\n }\n };\n\n const handlePlay = () => {\n // Hide controls when video starts playing (autoplay)\n if (!isMouseOver) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n videoWrapper.addEventListener(\"mouseenter\", showControls);\n videoWrapper.addEventListener(\"mouseleave\", hideControls);\n videoWrapper.addEventListener(\"mousemove\", handleMouseMove);\n video.addEventListener(\"pause\", showControls);\n video.addEventListener(\"play\", handlePlay);\n\n // Cleanup function\n return () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n videoWrapper.removeEventListener(\"mouseenter\", showControls);\n videoWrapper.removeEventListener(\"mouseleave\", hideControls);\n videoWrapper.removeEventListener(\"mousemove\", handleMouseMove);\n video.removeEventListener(\"pause\", showControls);\n video.removeEventListener(\"play\", handlePlay);\n };\n }\n }\n }, []);\n\n useEffect(() => {\n if (isFocused) {\n const handleClick = (event: MouseEvent) => {\n if (!videoWrapperRef.current?.contains(event.target as Node)) {\n setIsFocused(false);\n }\n };\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n document.removeEventListener(\"click\", handleClick);\n };\n }\n }, [isFocused]);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n setVideoRef,\n config: { clickToPlay: true, ...config },\n error,\n setError,\n isFocused,\n setIsFocused,\n }}\n >\n <div\n ref={videoWrapperRef}\n data-zuude-video-wrapper\n onClick={() => setIsFocused(true)}\n {...props}\n >\n {children}\n </div>\n </VideoContext.Provider>\n );\n }\n);\n\nexport const useVideo = () => {\n const context = useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n","import React, { forwardRef, RefObject, useEffect, useRef } from \"react\";\nimport { useVideo } from \"./wrapper\";\nimport { VideoAutoplay } from \"./types\";\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { Keyboards } from \"./keyboard\";\n\ninterface Props extends Omit<React.ComponentProps<\"video\">, \"autoPlay\"> {\n src: string;\n autoPlay?: VideoAutoplay;\n controls?: boolean;\n muteFallback?: (onMute: () => void) => React.ReactNode;\n}\n\nexport const Video = forwardRef<HTMLVideoElement, Props>(\n ({ src, autoPlay, muteFallback, controls, ...props }, ref) => {\n const { videoRef, setVideoRef, config, setError, error, isFocused } =\n useVideo();\n\n const refVideo = useRef<HTMLVideoElement>(null);\n\n useEffect(() => {\n const video = refVideo.current;\n const thirdPartyRef = ref;\n\n if (thirdPartyRef) {\n setVideoRef(thirdPartyRef as RefObject<HTMLVideoElement>);\n } else {\n if (video) {\n setVideoRef({ current: video });\n }\n }\n }, [src]);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" && props.muted === undefined,\n setError\n );\n\n const onPlay = () => {\n if (videoRef?.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef?.current?.pause();\n }\n };\n\n return (\n <>\n <video\n ref={ref || refVideo}\n data-zuude-video\n src={src}\n onClick={config?.clickToPlay ? onPlay : undefined}\n autoPlay={autoPlay === \"force\" ? true : autoPlay}\n {...props}\n />\n\n {controls && isFocused && <Keyboards />}\n\n {error === \"NotAllowedError\" &&\n typeof muteFallback === \"function\" &&\n muteFallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </>\n );\n }\n);\n\nVideo.displayName = \"Video\";\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayByForce = (\n videoRef: VideoRef,\n enabled: boolean,\n setError?: (error: string | null) => void\n) => {\n React.useEffect(() => {\n if (!videoRef?.current || !enabled) return;\n\n const playVideo = async () => {\n try {\n await videoRef.current?.play();\n } catch (error) {\n // If autoplay fails, try muting and playing again\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n setError?.(\"NotAllowedError\");\n console.error(\"NotAllowedError\");\n if (videoRef?.current) {\n videoRef.current.muted = true;\n try {\n await videoRef.current.play();\n } catch (retryError) {\n console.error(retryError);\n }\n }\n } else {\n console.error(error);\n }\n }\n };\n\n playVideo();\n }, [enabled, videoRef?.current]);\n};\n","import { useEffect } from \"react\";\n\nexport const useHotKeys = (\n key: string,\n func: (event: KeyboardEvent) => void,\n enabled = true\n) => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === key) {\n event.preventDefault();\n func(event);\n }\n };\n\n useEffect(() => {\n if (!enabled) return;\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [key, func, enabled]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSeek = (videoRef: VideoRef, value = 10) => {\n const seekForward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime += value;\n }\n }, [videoRef?.current]);\n\n const seekBackward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime -= value;\n }\n }, [videoRef?.current]);\n\n return { seekForward, seekBackward };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const usePlayPause = (videoRef: VideoRef) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n\n const togglePlay = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.paused\n ? videoRef.current.play()\n : videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n const play = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.play();\n }\n }, [videoRef?.current]);\n\n const pause = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const handlePlay = () => {\n setIsPlaying(true);\n };\n const handlePause = () => {\n setIsPlaying(false);\n };\n\n setIsPlaying(!videoRef?.current.paused);\n\n if (videoRef?.current) {\n videoRef.current.addEventListener(\"play\", handlePlay);\n videoRef.current.addEventListener(\"pause\", handlePause);\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", handlePlay);\n videoRef.current?.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n return { togglePlay, isPlaying, play, pause };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useMuteUnmute = (videoRef: VideoRef) => {\n const [isMuted, setIsMuted] = React.useState(false);\n\n const toggleMute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, [videoRef?.current]);\n\n const mute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = true;\n }\n }, [videoRef?.current]);\n\n const unmute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = false;\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n // Set the initial state\n setIsMuted(videoRef.current.muted);\n\n const handleVolumeChange = () => {\n if (videoRef.current) {\n setIsMuted(videoRef.current.muted);\n }\n };\n\n videoRef.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n videoRef.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [videoRef?.current]);\n\n return { toggleMute, isMuted, mute, unmute };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nconst useFullscreen = (videoRef: VideoRef) => {\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen?.(!!document.fullscreenElement);\n toggleFullscreen();\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, [isFullscreen]);\n\n const toggleFullscreen = () => {\n console.log(\"toggleFullscreen\");\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const video = videoRef?.current;\n\n if (video && isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n return;\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n return;\n }\n }\n\n const videoContainer = video?.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n\n if (videoContainer) {\n if (!isFullscreen) {\n videoContainer.requestFullscreen();\n if (video) {\n video.style.objectFit = \"contain\";\n }\n } else {\n document.exitFullscreen();\n if (video) {\n video.style.objectFit = \"cover\";\n }\n }\n }\n };\n\n return { isFullscreen: isFullscreen ?? false, toggleFullscreen };\n};\n\nexport { useFullscreen };\n","import type { VideoRef } from \"../types\";\n\nexport const usePictureInPicture = (videoRef: VideoRef) => {\n const togglePictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await video.requestPictureInPicture();\n }\n } catch (error) {\n // Fallback for browsers that don't support PiP\n const isSafari = /^((?!chrome|android).)*safari/i.test(\n navigator.userAgent\n );\n\n if (isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n }\n } else {\n const videoContainer = video.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n if (videoContainer) {\n if (!document.fullscreenElement) {\n await videoContainer.requestFullscreen();\n } else {\n await document.exitFullscreen();\n }\n }\n }\n }\n };\n\n const requestPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await video.requestPictureInPicture();\n };\n\n const exitPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await document.exitPictureInPicture();\n };\n\n return {\n togglePictureInPicture,\n requestPictureInPicture,\n exitPictureInPicture,\n };\n};\n","import { useVideo } from \"./wrapper\";\nimport { useHotKeys } from \"./hooks/use-hot-keys\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\n\nexport const Keyboards = () => {\n const { videoRef } = useVideo();\n\n const { seekForward, seekBackward } = useSeek(videoRef);\n const { togglePlay } = usePlayPause(videoRef);\n const { toggleMute } = useMuteUnmute(videoRef);\n const { toggleFullscreen } = useFullscreen(videoRef);\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n useHotKeys(\"ArrowRight\", () => {\n seekForward();\n });\n useHotKeys(\"ArrowLeft\", () => {\n seekBackward();\n });\n useHotKeys(\" \", () => {\n togglePlay();\n });\n useHotKeys(\"m\", () => {\n toggleMute();\n });\n useHotKeys(\"f\", () => {\n toggleFullscreen();\n });\n useHotKeys(\"p\", () => {\n togglePictureInPicture();\n });\n\n return null;\n};\n","import React, { RefObject } from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useVideo } from \"./wrapper\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\n\ninterface ControlsProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Controls = React.memo(\n ({ children, asChild, ...props }: ControlsProps) => {\n return (\n <div data-zuude-hide-elements {...props}>\n {children}\n </div>\n );\n }\n);\n\ninterface Props extends React.ComponentProps<\"button\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Play = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { play } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={play}>\n {children}\n </Element>\n );\n});\n\nconst Pause = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { pause } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={pause}>\n {children}\n </Element>\n );\n});\n\nconst Mute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { mute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={mute}>\n {children}\n </Element>\n );\n});\n\nconst Unmute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { unmute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={unmute}>\n {children}\n </Element>\n );\n});\n\nconst SeekForward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekForward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekForward}>\n {children}\n </Element>\n );\n});\n\nconst SeekBackward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekBackward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekBackward}>\n {children}\n </Element>\n );\n});\n\nconst Fullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst ExitFullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst Loading = () => {\n return <div>Loading</div>;\n};\n\nexport {\n Controls,\n Play,\n Pause,\n Mute,\n Unmute,\n SeekForward,\n SeekBackward,\n Fullscreen,\n ExitFullscreen,\n Loading,\n};\n"],"mappings":"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","names":["React","createContext","useContext","useEffect","useRef","useState","jsx","VideoContext","VideoProvider","children","config","onError","props","videoRef","setVideoRef","error","setError","isFocused","setIsFocused","videoWrapperRef","videoWrapper","controls","video","hideTimeout","hideDelay","isMouseOver","resetTimer","control","showControls","hideControls","handleMouseMove","handlePlay","handleClick","event","_a","useVideo","context","forwardRef","useEffect","useRef","React","useAutoplayByForce","videoRef","enabled","setError","_a","error","retryError","useEffect","useHotKeys","key","func","enabled","handleKeyDown","event","React","useSeek","videoRef","value","seekForward","seekBackward","React","usePlayPause","videoRef","isPlaying","setIsPlaying","togglePlay","play","pause","handlePlay","handlePause","_a","_b","React","useMuteUnmute","videoRef","isMuted","setIsMuted","toggleMute","mute","unmute","handleVolumeChange","_a","React","useFullscreen","videoRef","isFullscreen","setIsFullscreen","handleFullscreenChange","toggleFullscreen","isSafari","video","videoContainer","usePictureInPicture","videoRef","video","error","videoContainer","Keyboards","videoRef","useVideo","seekForward","seekBackward","useSeek","togglePlay","usePlayPause","toggleMute","useMuteUnmute","toggleFullscreen","useFullscreen","togglePictureInPicture","usePictureInPicture","useHotKeys","Fragment","jsx","jsxs","Video","forwardRef","src","autoPlay","muteFallback","controls","props","ref","videoRef","setVideoRef","config","setError","error","isFocused","useVideo","refVideo","useRef","useEffect","video","thirdPartyRef","useAutoplayByForce","onPlay","_a","_b","_c","Keyboards","React","Slot","jsx","Controls","React","children","asChild","props","Play","Element","Slot","videoRef","useVideo","play","usePlayPause","Pause","pause","Mute","mute","useMuteUnmute","Unmute","unmute","SeekForward","seekForward","useSeek","SeekBackward","seekBackward","Fullscreen","toggleFullscreen","useFullscreen","ExitFullscreen","Loading"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var d=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var x=(o,t)=>{for(var s in t)d(o,s,{get:t[s],enumerable:!0})},y=(o,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of F(t))!w.call(o,r)&&r!==s&&d(o,r,{get:()=>t[r],enumerable:!(n=T(t,r))||n.enumerable});return o};var L=o=>y(d({},"__esModule",{value:!0}),o);var Z={};x(Z,{compactTime:()=>b,detailedTime:()=>M,formatTime:()=>$,formatTimeForAccessibility:()=>O,formatTimeWithPercentage:()=>A,getTimeSegments:()=>H,humanizeTime:()=>g,parseTime:()=>W,timeRemaining:()=>z});module.exports=L(Z);function $(o,t="mm:ss"){let s=typeof t=="string"?{format:t}:t,{format:n="mm:ss",showHours:r=!0,showLeadingZeros:i=!0,showMilliseconds:c=!1,humanize:a=!1,compact:m=!1}=s;if(a)return g(o,{compact:m});let u=Math.floor(o),h=Math.floor(u/3600),l=Math.floor(u%3600/60),f=u%60,j=Math.floor(o%1*1e3),e=(p,S=2)=>i?p.toString().padStart(S,"0"):p.toString();switch(n){case"h:mm:ss":return`${e(h)}:${e(l)}:${e(f)}`;case"mm:ss":return r&&h>0?`${e(h)}:${e(l)}:${e(f)}`:`${e(l)}:${e(f)}`;case"ss":return`${u}s`;case"compact":return b(o);case"detailed":return M(o,{showMilliseconds:c});default:return`${e(l)}:${e(f)}`}}function g(o,t={}){let{compact:s=!1}=t,n=Math.floor(o);if(n<60)return`${n} second${n!==1?"s":""}`;let r=Math.floor(n/3600),i=Math.floor(n%3600/60),c=n%60,a=[];return r>0&&a.push(`${r} hour${r!==1?"s":""}`),i>0&&a.push(`${i} minute${i!==1?"s":""}`),c>0&&!s&&a.push(`${c} second${c!==1?"s":""}`),a.join(" ")}function b(o){let t=Math.floor(o),s=Math.floor(t/3600),n=Math.floor(t%3600/60),r=t%60;return s>0?`${s}:${n.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}`:`${n}:${r.toString().padStart(2,"0")}`}function M(o,t={}){let{showMilliseconds:s=!1}=t,n=Math.floor(o),r=Math.floor(n/3600),i=Math.floor(n%3600/60),c=n%60,a=Math.floor(o%1*1e3),m=`${r.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}:${c.toString().padStart(2,"0")}`;return s&&(m+=`.${a.toString().padStart(3,"0")}`),m}function W(o){let t=o.toLowerCase().trim();if(t.endsWith("s"))return parseFloat(t.slice(0,-1));if(t.endsWith("m"))return parseFloat(t.slice(0,-1))*60;if(t.endsWith("h"))return parseFloat(t.slice(0,-1))*3600;let s=o.split(":").map(Number);return s.length===2?(s[0]||0)*60+(s[1]||0):s.length===3?(s[0]||0)*3600+(s[1]||0)*60+(s[2]||0):parseFloat(o)||0}function z(o,t,s="mm:ss"){let n=Math.max(0,t-o);return $(n,s)}function A(o,t,s="mm:ss"){let n=t>0?Math.round(o/t*100):0;return`${$(o,s)} (${n}%)`}function H(o,t=10){return Array.from({length:t+1},(s,n)=>o/t*n)}function O(o){let t=Math.floor(o),s=Math.floor(t/3600),n=Math.floor(t%3600/60),r=t%60;return s>0?`${s} hours, ${n} minutes, ${r} seconds`:n>0?`${n} minutes, ${r} seconds`:`${r} seconds`}0&&(module.exports={compactTime,detailedTime,formatTime,formatTimeForAccessibility,formatTimeWithPercentage,getTimeSegments,humanizeTime,parseTime,timeRemaining});
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["// Video Time Formatting Utilities - Similar to date-fns but for video durations\n\nexport type TimeFormat =\n | \"h:mm:ss\"\n | \"mm:ss\"\n | \"ss\"\n | \"human\"\n | \"compact\"\n | \"detailed\";\n\nexport interface TimeFormatOptions {\n format?: TimeFormat;\n showHours?: boolean;\n showLeadingZeros?: boolean;\n showMilliseconds?: boolean;\n humanize?: boolean;\n compact?: boolean;\n}\n\n/**\n * Format time in seconds to various formats\n */\nfunction formatTime(\n time: number,\n options: TimeFormatOptions | TimeFormat = \"mm:ss\"\n): string {\n const opts = typeof options === \"string\" ? { format: options } : options;\n const {\n format = \"mm:ss\",\n showHours = true,\n showLeadingZeros = true,\n showMilliseconds = false,\n humanize = false,\n compact = false,\n } = opts;\n\n if (humanize) {\n return humanizeTime(time, { compact });\n }\n\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const milliseconds = Math.floor((time % 1) * 1000);\n\n const pad = (num: number, size: number = 2) =>\n showLeadingZeros ? num.toString().padStart(size, \"0\") : num.toString();\n\n switch (format) {\n case \"h:mm:ss\":\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\n case \"mm:ss\":\n return showHours && hours > 0\n ? `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`\n : `${pad(minutes)}:${pad(seconds)}`;\n case \"ss\":\n return `${totalSeconds}s`;\n case \"compact\":\n return compactTime(time);\n case \"detailed\":\n return detailedTime(time, { showMilliseconds });\n default:\n return `${pad(minutes)}:${pad(seconds)}`;\n }\n}\n\n/**\n * Humanize time duration (e.g., \"2 minutes 30 seconds\")\n */\nfunction humanizeTime(\n time: number,\n options: { compact?: boolean } = {}\n): string {\n const { compact = false } = options;\n const totalSeconds = Math.floor(time);\n\n if (totalSeconds < 60) {\n return `${totalSeconds} second${totalSeconds !== 1 ? \"s\" : \"\"}`;\n }\n\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n const parts: string[] = [];\n\n if (hours > 0) {\n parts.push(`${hours} hour${hours !== 1 ? \"s\" : \"\"}`);\n }\n\n if (minutes > 0) {\n parts.push(`${minutes} minute${minutes !== 1 ? \"s\" : \"\"}`);\n }\n\n if (seconds > 0 && !compact) {\n parts.push(`${seconds} second${seconds !== 1 ? \"s\" : \"\"}`);\n }\n\n return parts.join(\" \");\n}\n\n/**\n * Compact time format (e.g., \"2:30\" for 2 minutes 30 seconds)\n */\nfunction compactTime(time: number): string {\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n }\n\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\n/**\n * Detailed time format with milliseconds\n */\nfunction detailedTime(\n time: number,\n options: { showMilliseconds?: boolean } = {}\n): string {\n const { showMilliseconds = false } = options;\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const milliseconds = Math.floor((time % 1) * 1000);\n\n let result = `${hours.toString().padStart(2, \"0\")}:${minutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n\n if (showMilliseconds) {\n result += `.${milliseconds.toString().padStart(3, \"0\")}`;\n }\n\n return result;\n}\n\n/**\n * Parse time string to seconds\n */\nfunction parseTime(timeString: string): number {\n // Handle formats like \"2:30\", \"1:23:45\", \"90s\", \"1.5m\"\n const timeStringLower = timeString.toLowerCase().trim();\n\n // Handle seconds format \"90s\"\n if (timeStringLower.endsWith(\"s\")) {\n return parseFloat(timeStringLower.slice(0, -1));\n }\n\n // Handle minutes format \"1.5m\"\n if (timeStringLower.endsWith(\"m\")) {\n return parseFloat(timeStringLower.slice(0, -1)) * 60;\n }\n\n // Handle hours format \"1.5h\"\n if (timeStringLower.endsWith(\"h\")) {\n return parseFloat(timeStringLower.slice(0, -1)) * 3600;\n }\n\n // Handle HH:MM:SS or MM:SS format\n const parts = timeString.split(\":\").map(Number);\n\n if (parts.length === 2) {\n // MM:SS format\n return (parts[0] || 0) * 60 + (parts[1] || 0);\n } else if (parts.length === 3) {\n // HH:MM:SS format\n return (parts[0] || 0) * 3600 + (parts[1] || 0) * 60 + (parts[2] || 0);\n }\n\n // Fallback to parsing as seconds\n return parseFloat(timeString) || 0;\n}\n\n/**\n * Calculate time remaining\n */\nfunction timeRemaining(\n current: number,\n total: number,\n format: TimeFormat = \"mm:ss\"\n): string {\n const remaining = Math.max(0, total - current);\n return formatTime(remaining, format);\n}\n\n/**\n * Format time with percentage\n */\nfunction formatTimeWithPercentage(\n current: number,\n total: number,\n format: TimeFormat = \"mm:ss\"\n): string {\n const percentage = total > 0 ? Math.round((current / total) * 100) : 0;\n return `${formatTime(current, format)} (${percentage}%)`;\n}\n\n/**\n * Get time segments for timeline\n */\nfunction getTimeSegments(duration: number, segments: number = 10): number[] {\n return Array.from(\n { length: segments + 1 },\n (_, i) => (duration / segments) * i\n );\n}\n\n/**\n * Format time for accessibility (screen readers)\n */\nfunction formatTimeForAccessibility(time: number): string {\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours} hours, ${minutes} minutes, ${seconds} seconds`;\n } else if (minutes > 0) {\n return `${minutes} minutes, ${seconds} seconds`;\n } else {\n return `${seconds} seconds`;\n }\n}\n\nexport {\n formatTime,\n humanizeTime,\n compactTime,\n detailedTime,\n parseTime,\n timeRemaining,\n formatTimeWithPercentage,\n getTimeSegments,\n formatTimeForAccessibility,\n};\n"],"mappings":"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","names":["utils_exports","__export","compactTime","detailedTime","formatTime","formatTimeForAccessibility","formatTimeWithPercentage","getTimeSegments","humanizeTime","parseTime","timeRemaining","__toCommonJS","time","options","opts","format","showHours","showLeadingZeros","showMilliseconds","humanize","compact","totalSeconds","hours","minutes","seconds","milliseconds","pad","num","size","parts","result","timeString","timeStringLower","current","total","remaining","percentage","duration","segments","_","i"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type TimeFormat = "h:mm:ss" | "mm:ss" | "ss" | "human" | "compact" | "detailed";
|
|
2
|
+
interface TimeFormatOptions {
|
|
3
|
+
format?: TimeFormat;
|
|
4
|
+
showHours?: boolean;
|
|
5
|
+
showLeadingZeros?: boolean;
|
|
6
|
+
showMilliseconds?: boolean;
|
|
7
|
+
humanize?: boolean;
|
|
8
|
+
compact?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Format time in seconds to various formats
|
|
12
|
+
*/
|
|
13
|
+
declare function formatTime(time: number, options?: TimeFormatOptions | TimeFormat): string;
|
|
14
|
+
/**
|
|
15
|
+
* Humanize time duration (e.g., "2 minutes 30 seconds")
|
|
16
|
+
*/
|
|
17
|
+
declare function humanizeTime(time: number, options?: {
|
|
18
|
+
compact?: boolean;
|
|
19
|
+
}): string;
|
|
20
|
+
/**
|
|
21
|
+
* Compact time format (e.g., "2:30" for 2 minutes 30 seconds)
|
|
22
|
+
*/
|
|
23
|
+
declare function compactTime(time: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* Detailed time format with milliseconds
|
|
26
|
+
*/
|
|
27
|
+
declare function detailedTime(time: number, options?: {
|
|
28
|
+
showMilliseconds?: boolean;
|
|
29
|
+
}): string;
|
|
30
|
+
/**
|
|
31
|
+
* Parse time string to seconds
|
|
32
|
+
*/
|
|
33
|
+
declare function parseTime(timeString: string): number;
|
|
34
|
+
/**
|
|
35
|
+
* Calculate time remaining
|
|
36
|
+
*/
|
|
37
|
+
declare function timeRemaining(current: number, total: number, format?: TimeFormat): string;
|
|
38
|
+
/**
|
|
39
|
+
* Format time with percentage
|
|
40
|
+
*/
|
|
41
|
+
declare function formatTimeWithPercentage(current: number, total: number, format?: TimeFormat): string;
|
|
42
|
+
/**
|
|
43
|
+
* Get time segments for timeline
|
|
44
|
+
*/
|
|
45
|
+
declare function getTimeSegments(duration: number, segments?: number): number[];
|
|
46
|
+
/**
|
|
47
|
+
* Format time for accessibility (screen readers)
|
|
48
|
+
*/
|
|
49
|
+
declare function formatTimeForAccessibility(time: number): string;
|
|
50
|
+
|
|
51
|
+
export { type TimeFormat, type TimeFormatOptions, compactTime, detailedTime, formatTime, formatTimeForAccessibility, formatTimeWithPercentage, getTimeSegments, humanizeTime, parseTime, timeRemaining };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type TimeFormat = "h:mm:ss" | "mm:ss" | "ss" | "human" | "compact" | "detailed";
|
|
2
|
+
interface TimeFormatOptions {
|
|
3
|
+
format?: TimeFormat;
|
|
4
|
+
showHours?: boolean;
|
|
5
|
+
showLeadingZeros?: boolean;
|
|
6
|
+
showMilliseconds?: boolean;
|
|
7
|
+
humanize?: boolean;
|
|
8
|
+
compact?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Format time in seconds to various formats
|
|
12
|
+
*/
|
|
13
|
+
declare function formatTime(time: number, options?: TimeFormatOptions | TimeFormat): string;
|
|
14
|
+
/**
|
|
15
|
+
* Humanize time duration (e.g., "2 minutes 30 seconds")
|
|
16
|
+
*/
|
|
17
|
+
declare function humanizeTime(time: number, options?: {
|
|
18
|
+
compact?: boolean;
|
|
19
|
+
}): string;
|
|
20
|
+
/**
|
|
21
|
+
* Compact time format (e.g., "2:30" for 2 minutes 30 seconds)
|
|
22
|
+
*/
|
|
23
|
+
declare function compactTime(time: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* Detailed time format with milliseconds
|
|
26
|
+
*/
|
|
27
|
+
declare function detailedTime(time: number, options?: {
|
|
28
|
+
showMilliseconds?: boolean;
|
|
29
|
+
}): string;
|
|
30
|
+
/**
|
|
31
|
+
* Parse time string to seconds
|
|
32
|
+
*/
|
|
33
|
+
declare function parseTime(timeString: string): number;
|
|
34
|
+
/**
|
|
35
|
+
* Calculate time remaining
|
|
36
|
+
*/
|
|
37
|
+
declare function timeRemaining(current: number, total: number, format?: TimeFormat): string;
|
|
38
|
+
/**
|
|
39
|
+
* Format time with percentage
|
|
40
|
+
*/
|
|
41
|
+
declare function formatTimeWithPercentage(current: number, total: number, format?: TimeFormat): string;
|
|
42
|
+
/**
|
|
43
|
+
* Get time segments for timeline
|
|
44
|
+
*/
|
|
45
|
+
declare function getTimeSegments(duration: number, segments?: number): number[];
|
|
46
|
+
/**
|
|
47
|
+
* Format time for accessibility (screen readers)
|
|
48
|
+
*/
|
|
49
|
+
declare function formatTimeForAccessibility(time: number): string;
|
|
50
|
+
|
|
51
|
+
export { type TimeFormat, type TimeFormatOptions, compactTime, detailedTime, formatTime, formatTimeForAccessibility, formatTimeWithPercentage, getTimeSegments, humanizeTime, parseTime, timeRemaining };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function $(o,t="mm:ss"){let n=typeof t=="string"?{format:t}:t,{format:s="mm:ss",showHours:r=!0,showLeadingZeros:i=!0,showMilliseconds:c=!1,humanize:a=!1,compact:m=!1}=n;if(a)return g(o,{compact:m});let u=Math.floor(o),h=Math.floor(u/3600),l=Math.floor(u%3600/60),f=u%60,S=Math.floor(o%1*1e3),e=(d,p=2)=>i?d.toString().padStart(p,"0"):d.toString();switch(s){case"h:mm:ss":return`${e(h)}:${e(l)}:${e(f)}`;case"mm:ss":return r&&h>0?`${e(h)}:${e(l)}:${e(f)}`:`${e(l)}:${e(f)}`;case"ss":return`${u}s`;case"compact":return b(o);case"detailed":return M(o,{showMilliseconds:c});default:return`${e(l)}:${e(f)}`}}function g(o,t={}){let{compact:n=!1}=t,s=Math.floor(o);if(s<60)return`${s} second${s!==1?"s":""}`;let r=Math.floor(s/3600),i=Math.floor(s%3600/60),c=s%60,a=[];return r>0&&a.push(`${r} hour${r!==1?"s":""}`),i>0&&a.push(`${i} minute${i!==1?"s":""}`),c>0&&!n&&a.push(`${c} second${c!==1?"s":""}`),a.join(" ")}function b(o){let t=Math.floor(o),n=Math.floor(t/3600),s=Math.floor(t%3600/60),r=t%60;return n>0?`${n}:${s.toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}`:`${s}:${r.toString().padStart(2,"0")}`}function M(o,t={}){let{showMilliseconds:n=!1}=t,s=Math.floor(o),r=Math.floor(s/3600),i=Math.floor(s%3600/60),c=s%60,a=Math.floor(o%1*1e3),m=`${r.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}:${c.toString().padStart(2,"0")}`;return n&&(m+=`.${a.toString().padStart(3,"0")}`),m}function T(o){let t=o.toLowerCase().trim();if(t.endsWith("s"))return parseFloat(t.slice(0,-1));if(t.endsWith("m"))return parseFloat(t.slice(0,-1))*60;if(t.endsWith("h"))return parseFloat(t.slice(0,-1))*3600;let n=o.split(":").map(Number);return n.length===2?(n[0]||0)*60+(n[1]||0):n.length===3?(n[0]||0)*3600+(n[1]||0)*60+(n[2]||0):parseFloat(o)||0}function F(o,t,n="mm:ss"){let s=Math.max(0,t-o);return $(s,n)}function w(o,t,n="mm:ss"){let s=t>0?Math.round(o/t*100):0;return`${$(o,n)} (${s}%)`}function x(o,t=10){return Array.from({length:t+1},(n,s)=>o/t*s)}function y(o){let t=Math.floor(o),n=Math.floor(t/3600),s=Math.floor(t%3600/60),r=t%60;return n>0?`${n} hours, ${s} minutes, ${r} seconds`:s>0?`${s} minutes, ${r} seconds`:`${r} seconds`}export{b as compactTime,M as detailedTime,$ as formatTime,y as formatTimeForAccessibility,w as formatTimeWithPercentage,x as getTimeSegments,g as humanizeTime,T as parseTime,F as timeRemaining};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["// Video Time Formatting Utilities - Similar to date-fns but for video durations\n\nexport type TimeFormat =\n | \"h:mm:ss\"\n | \"mm:ss\"\n | \"ss\"\n | \"human\"\n | \"compact\"\n | \"detailed\";\n\nexport interface TimeFormatOptions {\n format?: TimeFormat;\n showHours?: boolean;\n showLeadingZeros?: boolean;\n showMilliseconds?: boolean;\n humanize?: boolean;\n compact?: boolean;\n}\n\n/**\n * Format time in seconds to various formats\n */\nfunction formatTime(\n time: number,\n options: TimeFormatOptions | TimeFormat = \"mm:ss\"\n): string {\n const opts = typeof options === \"string\" ? { format: options } : options;\n const {\n format = \"mm:ss\",\n showHours = true,\n showLeadingZeros = true,\n showMilliseconds = false,\n humanize = false,\n compact = false,\n } = opts;\n\n if (humanize) {\n return humanizeTime(time, { compact });\n }\n\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const milliseconds = Math.floor((time % 1) * 1000);\n\n const pad = (num: number, size: number = 2) =>\n showLeadingZeros ? num.toString().padStart(size, \"0\") : num.toString();\n\n switch (format) {\n case \"h:mm:ss\":\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\n case \"mm:ss\":\n return showHours && hours > 0\n ? `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`\n : `${pad(minutes)}:${pad(seconds)}`;\n case \"ss\":\n return `${totalSeconds}s`;\n case \"compact\":\n return compactTime(time);\n case \"detailed\":\n return detailedTime(time, { showMilliseconds });\n default:\n return `${pad(minutes)}:${pad(seconds)}`;\n }\n}\n\n/**\n * Humanize time duration (e.g., \"2 minutes 30 seconds\")\n */\nfunction humanizeTime(\n time: number,\n options: { compact?: boolean } = {}\n): string {\n const { compact = false } = options;\n const totalSeconds = Math.floor(time);\n\n if (totalSeconds < 60) {\n return `${totalSeconds} second${totalSeconds !== 1 ? \"s\" : \"\"}`;\n }\n\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n const parts: string[] = [];\n\n if (hours > 0) {\n parts.push(`${hours} hour${hours !== 1 ? \"s\" : \"\"}`);\n }\n\n if (minutes > 0) {\n parts.push(`${minutes} minute${minutes !== 1 ? \"s\" : \"\"}`);\n }\n\n if (seconds > 0 && !compact) {\n parts.push(`${seconds} second${seconds !== 1 ? \"s\" : \"\"}`);\n }\n\n return parts.join(\" \");\n}\n\n/**\n * Compact time format (e.g., \"2:30\" for 2 minutes 30 seconds)\n */\nfunction compactTime(time: number): string {\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n }\n\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\n/**\n * Detailed time format with milliseconds\n */\nfunction detailedTime(\n time: number,\n options: { showMilliseconds?: boolean } = {}\n): string {\n const { showMilliseconds = false } = options;\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const milliseconds = Math.floor((time % 1) * 1000);\n\n let result = `${hours.toString().padStart(2, \"0\")}:${minutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n\n if (showMilliseconds) {\n result += `.${milliseconds.toString().padStart(3, \"0\")}`;\n }\n\n return result;\n}\n\n/**\n * Parse time string to seconds\n */\nfunction parseTime(timeString: string): number {\n // Handle formats like \"2:30\", \"1:23:45\", \"90s\", \"1.5m\"\n const timeStringLower = timeString.toLowerCase().trim();\n\n // Handle seconds format \"90s\"\n if (timeStringLower.endsWith(\"s\")) {\n return parseFloat(timeStringLower.slice(0, -1));\n }\n\n // Handle minutes format \"1.5m\"\n if (timeStringLower.endsWith(\"m\")) {\n return parseFloat(timeStringLower.slice(0, -1)) * 60;\n }\n\n // Handle hours format \"1.5h\"\n if (timeStringLower.endsWith(\"h\")) {\n return parseFloat(timeStringLower.slice(0, -1)) * 3600;\n }\n\n // Handle HH:MM:SS or MM:SS format\n const parts = timeString.split(\":\").map(Number);\n\n if (parts.length === 2) {\n // MM:SS format\n return (parts[0] || 0) * 60 + (parts[1] || 0);\n } else if (parts.length === 3) {\n // HH:MM:SS format\n return (parts[0] || 0) * 3600 + (parts[1] || 0) * 60 + (parts[2] || 0);\n }\n\n // Fallback to parsing as seconds\n return parseFloat(timeString) || 0;\n}\n\n/**\n * Calculate time remaining\n */\nfunction timeRemaining(\n current: number,\n total: number,\n format: TimeFormat = \"mm:ss\"\n): string {\n const remaining = Math.max(0, total - current);\n return formatTime(remaining, format);\n}\n\n/**\n * Format time with percentage\n */\nfunction formatTimeWithPercentage(\n current: number,\n total: number,\n format: TimeFormat = \"mm:ss\"\n): string {\n const percentage = total > 0 ? Math.round((current / total) * 100) : 0;\n return `${formatTime(current, format)} (${percentage}%)`;\n}\n\n/**\n * Get time segments for timeline\n */\nfunction getTimeSegments(duration: number, segments: number = 10): number[] {\n return Array.from(\n { length: segments + 1 },\n (_, i) => (duration / segments) * i\n );\n}\n\n/**\n * Format time for accessibility (screen readers)\n */\nfunction formatTimeForAccessibility(time: number): string {\n const totalSeconds = Math.floor(time);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours} hours, ${minutes} minutes, ${seconds} seconds`;\n } else if (minutes > 0) {\n return `${minutes} minutes, ${seconds} seconds`;\n } else {\n return `${seconds} seconds`;\n }\n}\n\nexport {\n formatTime,\n humanizeTime,\n compactTime,\n detailedTime,\n parseTime,\n timeRemaining,\n formatTimeWithPercentage,\n getTimeSegments,\n formatTimeForAccessibility,\n};\n"],"mappings":"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","names":["formatTime","time","options","opts","format","showHours","showLeadingZeros","showMilliseconds","humanize","compact","humanizeTime","totalSeconds","hours","minutes","seconds","milliseconds","pad","num","size","compactTime","detailedTime","parts","result","parseTime","timeString","timeStringLower","timeRemaining","current","total","remaining","formatTimeWithPercentage","percentage","getTimeSegments","duration","segments","_","i","formatTimeForAccessibility"]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.6",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"module": "./dist/index.mjs",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
@@ -17,10 +17,15 @@
|
|
|
17
17
|
"import": "./dist/index.cjs",
|
|
18
18
|
"require": "./dist/index.js"
|
|
19
19
|
},
|
|
20
|
-
"./
|
|
21
|
-
"types": "./dist/
|
|
22
|
-
"import": "./dist/
|
|
23
|
-
"require": "./dist/
|
|
20
|
+
"./hooks": {
|
|
21
|
+
"types": "./dist/hooks/index.d.ts",
|
|
22
|
+
"import": "./dist/hooks/index.cjs",
|
|
23
|
+
"require": "./dist/hooks/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./utils": {
|
|
26
|
+
"types": "./dist/utils/index.d.ts",
|
|
27
|
+
"import": "./dist/utils/index.cjs",
|
|
28
|
+
"require": "./dist/utils/index.js"
|
|
24
29
|
}
|
|
25
30
|
},
|
|
26
31
|
"scripts": {
|