@haklex/rich-renderer-video 0.0.39 → 0.0.41

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.
@@ -0,0 +1,333 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Slider } from "@base-ui/react/slider";
3
+ import { Play, Pause, VolumeX, Volume2, Loader2, Download, Minimize, Maximize } from "lucide-react";
4
+ import { useRef, useState, useMemo, useCallback, useEffect } from "react";
5
+ var semanticClassNames = { root: "rr-video-root", player: "rr-video-player", element: "rr-video-element", indicator: "rr-video-indicator", controls: "rr-video-controls", button: "rr-video-btn", progress: "rr-video-progress", progressControl: "rr-video-progress-control", progressTrack: "rr-video-progress-track", progressRange: "rr-video-progress-range", progressThumb: "rr-video-progress-thumb", spin: "rr-video-spin", editTrigger: "rr-video-edit-trigger", editPreview: "rr-video-edit-preview", editVideo: "rr-video-edit-video", editOverlay: "rr-video-edit-overlay", editPlaceholder: "rr-video-edit-placeholder", editPanel: "rr-video-edit-panel", editField: "rr-video-edit-field", editFieldIcon: "rr-video-edit-field-icon", editInput: "rr-video-edit-input", editActions: "rr-video-edit-actions", editActionButton: "rr-video-edit-action-btn", editActionButtonEnd: "rr-video-edit-action-btn--end" };
6
+ var root = "_1x2h1ol0";
7
+ var player = "_1x2h1ol1";
8
+ var element = "_1x2h1ol2";
9
+ var indicator = "_1x2h1ol4";
10
+ var controls = "_1x2h1ol5";
11
+ var button = "_1x2h1ol6";
12
+ var progress = "_1x2h1ol7";
13
+ var progressControl = "_1x2h1ol8";
14
+ var progressTrack = "_1x2h1ol9";
15
+ var progressRange = "_1x2h1ola";
16
+ var progressThumb = "_1x2h1olb";
17
+ var spin = "_1x2h1old";
18
+ var editTrigger = "_1x2h1ole";
19
+ var editPreview = "_1x2h1olf";
20
+ var editVideo = "_1x2h1olg";
21
+ var editOverlay = "_1x2h1olh";
22
+ var editPlaceholder = "_1x2h1oli";
23
+ var editPanel = "_1x2h1olj";
24
+ var editField = "_1x2h1olk";
25
+ var editFieldIcon = "_1x2h1oll";
26
+ var editInput = "_1x2h1olm";
27
+ var editActions = "_1x2h1oln";
28
+ var editActionButton = "_1x2h1olo";
29
+ var editActionButtonEnd = "_1x2h1olp";
30
+ const PlayIcon = ({ size = 20 }) => /* @__PURE__ */ jsx(Play, { size });
31
+ const PauseIcon = ({ size = 20 }) => /* @__PURE__ */ jsx(Pause, { size });
32
+ const VolumeIcon = () => /* @__PURE__ */ jsx(Volume2, { size: 20 });
33
+ const VolumeMuteIcon = () => /* @__PURE__ */ jsx(VolumeX, { size: 20 });
34
+ const DownloadIcon = () => /* @__PURE__ */ jsx(Download, { size: 20 });
35
+ const LoadingIcon = () => /* @__PURE__ */ jsx(
36
+ Loader2,
37
+ {
38
+ size: 20,
39
+ className: `${spin} ${semanticClassNames.spin}`
40
+ }
41
+ );
42
+ const FullscreenIcon = () => /* @__PURE__ */ jsx(Maximize, { size: 20 });
43
+ const ExitFullscreenIcon = () => /* @__PURE__ */ jsx(Minimize, { size: 20 });
44
+ const VideoRenderer = ({
45
+ src,
46
+ poster,
47
+ width,
48
+ height
49
+ }) => {
50
+ const wrapperRef = useRef(null);
51
+ const videoRef = useRef(null);
52
+ const [playing, setPlaying] = useState(false);
53
+ const [duration, setDuration] = useState(0);
54
+ const [currentTime, setCurrentTime] = useState(0);
55
+ const [muted, setMuted] = useState(false);
56
+ const [isFullscreen, setIsFullscreen] = useState(false);
57
+ const [indicator$1, setIndicator] = useState(null);
58
+ const [draggingTime, setDraggingTime] = useState(null);
59
+ const [isDownloading, setIsDownloading] = useState(false);
60
+ const dragWasPlayingRef = useRef(false);
61
+ const indicatorTimerRef = useRef(void 0);
62
+ const indicatorKeyRef = useRef(0);
63
+ const aspectRatio = useMemo(() => {
64
+ if (width && height && width > 0 && height > 0) {
65
+ return `${width} / ${height}`;
66
+ }
67
+ return "16 / 9";
68
+ }, [height, width]);
69
+ const showIndicator = useCallback((type) => {
70
+ indicatorKeyRef.current += 1;
71
+ setIndicator({ type, key: indicatorKeyRef.current });
72
+ clearTimeout(indicatorTimerRef.current);
73
+ indicatorTimerRef.current = setTimeout(() => setIndicator(null), 500);
74
+ }, []);
75
+ const play = useCallback(() => {
76
+ void videoRef.current?.play();
77
+ }, []);
78
+ const pause = useCallback(() => {
79
+ videoRef.current?.pause();
80
+ }, []);
81
+ const togglePlay = useCallback(() => {
82
+ const video = videoRef.current;
83
+ if (!video) return;
84
+ if (video.paused) {
85
+ play();
86
+ showIndicator("play");
87
+ } else {
88
+ pause();
89
+ showIndicator("pause");
90
+ }
91
+ }, [pause, play, showIndicator]);
92
+ const seekTo = useCallback((time) => {
93
+ const video = videoRef.current;
94
+ if (!video) return;
95
+ const clamped = Math.min(
96
+ Math.max(0, time),
97
+ Number.isFinite(video.duration) ? video.duration : time
98
+ );
99
+ video.currentTime = clamped;
100
+ setCurrentTime(clamped);
101
+ }, []);
102
+ const toggleMute = useCallback(() => {
103
+ const video = videoRef.current;
104
+ if (!video) return;
105
+ video.muted = !video.muted;
106
+ setMuted(video.muted);
107
+ }, []);
108
+ const toggleFullscreen = useCallback(() => {
109
+ const wrapper = wrapperRef.current;
110
+ if (!wrapper) return;
111
+ if (!document.fullscreenElement) {
112
+ void wrapper.requestFullscreen();
113
+ } else {
114
+ void document.exitFullscreen();
115
+ }
116
+ }, []);
117
+ const downloadingRef = useRef(false);
118
+ const downloadVideo = useCallback(() => {
119
+ if (downloadingRef.current) return;
120
+ downloadingRef.current = true;
121
+ setIsDownloading(true);
122
+ const filename = src.split("/").pop() || "video";
123
+ const fallback = () => {
124
+ const a = document.createElement("a");
125
+ a.href = src;
126
+ a.download = filename;
127
+ a.rel = "noopener noreferrer";
128
+ a.click();
129
+ };
130
+ fetch(src).then((res) => {
131
+ if (!res.ok) throw new Error(res.statusText);
132
+ return res.blob();
133
+ }).then((blob) => {
134
+ const url = URL.createObjectURL(blob);
135
+ const a = document.createElement("a");
136
+ a.href = url;
137
+ a.download = filename;
138
+ a.click();
139
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
140
+ }).catch(() => fallback()).finally(() => {
141
+ downloadingRef.current = false;
142
+ setIsDownloading(false);
143
+ });
144
+ }, [src]);
145
+ useEffect(() => {
146
+ const video = videoRef.current;
147
+ if (!video) return;
148
+ const onLoadedMetadata = () => {
149
+ setDuration(Number.isFinite(video.duration) ? video.duration : 0);
150
+ setMuted(video.muted);
151
+ };
152
+ const onDurationChange = () => {
153
+ setDuration(Number.isFinite(video.duration) ? video.duration : 0);
154
+ };
155
+ const onTimeUpdate = () => setCurrentTime(video.currentTime);
156
+ const onPlay = () => setPlaying(true);
157
+ const onPause = () => setPlaying(false);
158
+ const onVolumeChange = () => setMuted(video.muted);
159
+ video.addEventListener("loadedmetadata", onLoadedMetadata);
160
+ video.addEventListener("durationchange", onDurationChange);
161
+ video.addEventListener("timeupdate", onTimeUpdate);
162
+ video.addEventListener("play", onPlay);
163
+ video.addEventListener("pause", onPause);
164
+ video.addEventListener("volumechange", onVolumeChange);
165
+ return () => {
166
+ video.removeEventListener("loadedmetadata", onLoadedMetadata);
167
+ video.removeEventListener("durationchange", onDurationChange);
168
+ video.removeEventListener("timeupdate", onTimeUpdate);
169
+ video.removeEventListener("play", onPlay);
170
+ video.removeEventListener("pause", onPause);
171
+ video.removeEventListener("volumechange", onVolumeChange);
172
+ };
173
+ }, []);
174
+ useEffect(() => {
175
+ const handler = () => setIsFullscreen(!!document.fullscreenElement);
176
+ document.addEventListener("fullscreenchange", handler);
177
+ return () => document.removeEventListener("fullscreenchange", handler);
178
+ }, []);
179
+ useEffect(() => {
180
+ return () => clearTimeout(indicatorTimerRef.current);
181
+ }, []);
182
+ const timelineValue = draggingTime ?? currentTime;
183
+ return /* @__PURE__ */ jsx("figure", { className: `${root} ${semanticClassNames.root}`, children: /* @__PURE__ */ jsxs(
184
+ "div",
185
+ {
186
+ className: `${player} ${semanticClassNames.player}`,
187
+ ref: wrapperRef,
188
+ style: { aspectRatio },
189
+ children: [
190
+ /* @__PURE__ */ jsx(
191
+ "video",
192
+ {
193
+ ref: videoRef,
194
+ className: `${element} ${semanticClassNames.element}`,
195
+ src,
196
+ poster,
197
+ preload: "metadata",
198
+ playsInline: true,
199
+ onClick: togglePlay,
200
+ onDoubleClick: toggleFullscreen
201
+ }
202
+ ),
203
+ indicator$1 && /* @__PURE__ */ jsx(
204
+ "span",
205
+ {
206
+ className: `${indicator} ${semanticClassNames.indicator}`,
207
+ "aria-hidden": true,
208
+ children: indicator$1.type === "play" ? /* @__PURE__ */ jsx(PlayIcon, { size: 32 }) : /* @__PURE__ */ jsx(PauseIcon, { size: 32 })
209
+ },
210
+ indicator$1.key
211
+ ),
212
+ /* @__PURE__ */ jsxs(
213
+ "div",
214
+ {
215
+ className: `${controls} ${semanticClassNames.controls}`,
216
+ onClick: (e) => e.stopPropagation(),
217
+ children: [
218
+ /* @__PURE__ */ jsx(
219
+ "button",
220
+ {
221
+ type: "button",
222
+ className: `${button} ${semanticClassNames.button}`,
223
+ "aria-label": playing ? "Pause" : "Play",
224
+ onClick: togglePlay,
225
+ children: playing ? /* @__PURE__ */ jsx(PauseIcon, {}) : /* @__PURE__ */ jsx(PlayIcon, {})
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsx(
229
+ Slider.Root,
230
+ {
231
+ className: `${progress} ${semanticClassNames.progress}`,
232
+ min: 0,
233
+ max: duration || 0,
234
+ step: 0.01,
235
+ value: timelineValue,
236
+ onValueChange: (value) => {
237
+ setDraggingTime(value);
238
+ },
239
+ onValueCommitted: (value) => {
240
+ seekTo(value);
241
+ setDraggingTime(null);
242
+ if (dragWasPlayingRef.current) {
243
+ play();
244
+ }
245
+ },
246
+ children: /* @__PURE__ */ jsx(
247
+ Slider.Control,
248
+ {
249
+ className: `${progressControl} ${semanticClassNames.progressControl}`,
250
+ onPointerDown: () => {
251
+ dragWasPlayingRef.current = playing;
252
+ pause();
253
+ setDraggingTime(currentTime);
254
+ },
255
+ children: /* @__PURE__ */ jsxs(
256
+ Slider.Track,
257
+ {
258
+ className: `${progressTrack} ${semanticClassNames.progressTrack}`,
259
+ children: [
260
+ /* @__PURE__ */ jsx(
261
+ Slider.Indicator,
262
+ {
263
+ className: `${progressRange} ${semanticClassNames.progressRange}`
264
+ }
265
+ ),
266
+ /* @__PURE__ */ jsx(
267
+ Slider.Thumb,
268
+ {
269
+ className: `${progressThumb} ${semanticClassNames.progressThumb}`,
270
+ "aria-label": "Playback progress"
271
+ }
272
+ )
273
+ ]
274
+ }
275
+ )
276
+ }
277
+ )
278
+ }
279
+ ),
280
+ /* @__PURE__ */ jsx(
281
+ "button",
282
+ {
283
+ type: "button",
284
+ className: `${button} ${semanticClassNames.button}`,
285
+ "aria-label": muted ? "Unmute" : "Mute",
286
+ onClick: toggleMute,
287
+ children: muted ? /* @__PURE__ */ jsx(VolumeMuteIcon, {}) : /* @__PURE__ */ jsx(VolumeIcon, {})
288
+ }
289
+ ),
290
+ /* @__PURE__ */ jsx(
291
+ "button",
292
+ {
293
+ type: "button",
294
+ className: `${button} ${semanticClassNames.button}`,
295
+ "aria-label": "Download",
296
+ onClick: downloadVideo,
297
+ children: isDownloading ? /* @__PURE__ */ jsx(LoadingIcon, {}) : /* @__PURE__ */ jsx(DownloadIcon, {})
298
+ }
299
+ ),
300
+ /* @__PURE__ */ jsx(
301
+ "button",
302
+ {
303
+ type: "button",
304
+ className: `${button} ${semanticClassNames.button}`,
305
+ "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
306
+ onClick: toggleFullscreen,
307
+ children: isFullscreen ? /* @__PURE__ */ jsx(ExitFullscreenIcon, {}) : /* @__PURE__ */ jsx(FullscreenIcon, {})
308
+ }
309
+ )
310
+ ]
311
+ }
312
+ )
313
+ ]
314
+ }
315
+ ) });
316
+ };
317
+ export {
318
+ VideoRenderer as V,
319
+ editVideo as a,
320
+ editOverlay as b,
321
+ editPlaceholder as c,
322
+ editTrigger as d,
323
+ editPreview as e,
324
+ editPanel as f,
325
+ editField as g,
326
+ editFieldIcon as h,
327
+ editInput as i,
328
+ editActions as j,
329
+ editActionButton as k,
330
+ editActionButtonEnd as l,
331
+ root as r,
332
+ semanticClassNames as s
333
+ };
package/dist/index.mjs CHANGED
@@ -3,321 +3,9 @@ import { useRendererMode } from "@haklex/rich-editor";
3
3
  import { Popover, PopoverTrigger, PopoverPanel } from "@haklex/rich-editor-ui";
4
4
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
5
5
  import { $getNearestNodeFromDOMNode } from "lexical";
6
- import { Play, Pause, VolumeX, Volume2, Loader2, Download, Minimize, Maximize, Video, ImageIcon, ExternalLink, Trash2 } from "lucide-react";
7
- import { useRef, useState, useMemo, useCallback, useEffect } from "react";
8
- import { Slider } from "@base-ui/react/slider";
9
- var semanticClassNames = { root: "rr-video-root", player: "rr-video-player", element: "rr-video-element", indicator: "rr-video-indicator", controls: "rr-video-controls", button: "rr-video-btn", progress: "rr-video-progress", progressControl: "rr-video-progress-control", progressTrack: "rr-video-progress-track", progressRange: "rr-video-progress-range", progressThumb: "rr-video-progress-thumb", spin: "rr-video-spin", editTrigger: "rr-video-edit-trigger", editPreview: "rr-video-edit-preview", editVideo: "rr-video-edit-video", editOverlay: "rr-video-edit-overlay", editPlaceholder: "rr-video-edit-placeholder", editPanel: "rr-video-edit-panel", editField: "rr-video-edit-field", editFieldIcon: "rr-video-edit-field-icon", editInput: "rr-video-edit-input", editActions: "rr-video-edit-actions", editActionButton: "rr-video-edit-action-btn", editActionButtonEnd: "rr-video-edit-action-btn--end" };
10
- var root = "_1x2h1ol0";
11
- var player = "_1x2h1ol1";
12
- var element = "_1x2h1ol2";
13
- var indicator = "_1x2h1ol4";
14
- var controls = "_1x2h1ol5";
15
- var button = "_1x2h1ol6";
16
- var progress = "_1x2h1ol7";
17
- var progressControl = "_1x2h1ol8";
18
- var progressTrack = "_1x2h1ol9";
19
- var progressRange = "_1x2h1ola";
20
- var progressThumb = "_1x2h1olb";
21
- var spin = "_1x2h1old";
22
- var editTrigger = "_1x2h1ole";
23
- var editPreview = "_1x2h1olf";
24
- var editVideo = "_1x2h1olg";
25
- var editOverlay = "_1x2h1olh";
26
- var editPlaceholder = "_1x2h1oli";
27
- var editPanel = "_1x2h1olj";
28
- var editField = "_1x2h1olk";
29
- var editFieldIcon = "_1x2h1oll";
30
- var editInput = "_1x2h1olm";
31
- var editActions = "_1x2h1oln";
32
- var editActionButton = "_1x2h1olo";
33
- var editActionButtonEnd = "_1x2h1olp";
34
- const PlayIcon = ({ size = 20 }) => /* @__PURE__ */ jsx(Play, { size });
35
- const PauseIcon = ({ size = 20 }) => /* @__PURE__ */ jsx(Pause, { size });
36
- const VolumeIcon = () => /* @__PURE__ */ jsx(Volume2, { size: 20 });
37
- const VolumeMuteIcon = () => /* @__PURE__ */ jsx(VolumeX, { size: 20 });
38
- const DownloadIcon = () => /* @__PURE__ */ jsx(Download, { size: 20 });
39
- const LoadingIcon = () => /* @__PURE__ */ jsx(
40
- Loader2,
41
- {
42
- size: 20,
43
- className: `${spin} ${semanticClassNames.spin}`
44
- }
45
- );
46
- const FullscreenIcon = () => /* @__PURE__ */ jsx(Maximize, { size: 20 });
47
- const ExitFullscreenIcon = () => /* @__PURE__ */ jsx(Minimize, { size: 20 });
48
- const VideoRenderer = ({
49
- src,
50
- poster,
51
- width,
52
- height
53
- }) => {
54
- const wrapperRef = useRef(null);
55
- const videoRef = useRef(null);
56
- const [playing, setPlaying] = useState(false);
57
- const [duration, setDuration] = useState(0);
58
- const [currentTime, setCurrentTime] = useState(0);
59
- const [muted, setMuted] = useState(false);
60
- const [isFullscreen, setIsFullscreen] = useState(false);
61
- const [indicator$1, setIndicator] = useState(null);
62
- const [draggingTime, setDraggingTime] = useState(null);
63
- const [isDownloading, setIsDownloading] = useState(false);
64
- const dragWasPlayingRef = useRef(false);
65
- const indicatorTimerRef = useRef(void 0);
66
- const indicatorKeyRef = useRef(0);
67
- const aspectRatio = useMemo(() => {
68
- if (width && height && width > 0 && height > 0) {
69
- return `${width} / ${height}`;
70
- }
71
- return "16 / 9";
72
- }, [height, width]);
73
- const showIndicator = useCallback((type) => {
74
- indicatorKeyRef.current += 1;
75
- setIndicator({ type, key: indicatorKeyRef.current });
76
- clearTimeout(indicatorTimerRef.current);
77
- indicatorTimerRef.current = setTimeout(() => setIndicator(null), 500);
78
- }, []);
79
- const play = useCallback(() => {
80
- void videoRef.current?.play();
81
- }, []);
82
- const pause = useCallback(() => {
83
- videoRef.current?.pause();
84
- }, []);
85
- const togglePlay = useCallback(() => {
86
- const video = videoRef.current;
87
- if (!video) return;
88
- if (video.paused) {
89
- play();
90
- showIndicator("play");
91
- } else {
92
- pause();
93
- showIndicator("pause");
94
- }
95
- }, [pause, play, showIndicator]);
96
- const seekTo = useCallback((time) => {
97
- const video = videoRef.current;
98
- if (!video) return;
99
- const clamped = Math.min(
100
- Math.max(0, time),
101
- Number.isFinite(video.duration) ? video.duration : time
102
- );
103
- video.currentTime = clamped;
104
- setCurrentTime(clamped);
105
- }, []);
106
- const toggleMute = useCallback(() => {
107
- const video = videoRef.current;
108
- if (!video) return;
109
- video.muted = !video.muted;
110
- setMuted(video.muted);
111
- }, []);
112
- const toggleFullscreen = useCallback(() => {
113
- const wrapper = wrapperRef.current;
114
- if (!wrapper) return;
115
- if (!document.fullscreenElement) {
116
- void wrapper.requestFullscreen();
117
- } else {
118
- void document.exitFullscreen();
119
- }
120
- }, []);
121
- const downloadingRef = useRef(false);
122
- const downloadVideo = useCallback(() => {
123
- if (downloadingRef.current) return;
124
- downloadingRef.current = true;
125
- setIsDownloading(true);
126
- const filename = src.split("/").pop() || "video";
127
- const fallback = () => {
128
- const a = document.createElement("a");
129
- a.href = src;
130
- a.download = filename;
131
- a.rel = "noopener noreferrer";
132
- a.click();
133
- };
134
- fetch(src).then((res) => {
135
- if (!res.ok) throw new Error(res.statusText);
136
- return res.blob();
137
- }).then((blob) => {
138
- const url = URL.createObjectURL(blob);
139
- const a = document.createElement("a");
140
- a.href = url;
141
- a.download = filename;
142
- a.click();
143
- setTimeout(() => URL.revokeObjectURL(url), 1e3);
144
- }).catch(() => fallback()).finally(() => {
145
- downloadingRef.current = false;
146
- setIsDownloading(false);
147
- });
148
- }, [src]);
149
- useEffect(() => {
150
- const video = videoRef.current;
151
- if (!video) return;
152
- const onLoadedMetadata = () => {
153
- setDuration(Number.isFinite(video.duration) ? video.duration : 0);
154
- setMuted(video.muted);
155
- };
156
- const onDurationChange = () => {
157
- setDuration(Number.isFinite(video.duration) ? video.duration : 0);
158
- };
159
- const onTimeUpdate = () => setCurrentTime(video.currentTime);
160
- const onPlay = () => setPlaying(true);
161
- const onPause = () => setPlaying(false);
162
- const onVolumeChange = () => setMuted(video.muted);
163
- video.addEventListener("loadedmetadata", onLoadedMetadata);
164
- video.addEventListener("durationchange", onDurationChange);
165
- video.addEventListener("timeupdate", onTimeUpdate);
166
- video.addEventListener("play", onPlay);
167
- video.addEventListener("pause", onPause);
168
- video.addEventListener("volumechange", onVolumeChange);
169
- return () => {
170
- video.removeEventListener("loadedmetadata", onLoadedMetadata);
171
- video.removeEventListener("durationchange", onDurationChange);
172
- video.removeEventListener("timeupdate", onTimeUpdate);
173
- video.removeEventListener("play", onPlay);
174
- video.removeEventListener("pause", onPause);
175
- video.removeEventListener("volumechange", onVolumeChange);
176
- };
177
- }, []);
178
- useEffect(() => {
179
- const handler = () => setIsFullscreen(!!document.fullscreenElement);
180
- document.addEventListener("fullscreenchange", handler);
181
- return () => document.removeEventListener("fullscreenchange", handler);
182
- }, []);
183
- useEffect(() => {
184
- return () => clearTimeout(indicatorTimerRef.current);
185
- }, []);
186
- const timelineValue = draggingTime ?? currentTime;
187
- return /* @__PURE__ */ jsx("figure", { className: `${root} ${semanticClassNames.root}`, children: /* @__PURE__ */ jsxs(
188
- "div",
189
- {
190
- className: `${player} ${semanticClassNames.player}`,
191
- ref: wrapperRef,
192
- style: { aspectRatio },
193
- children: [
194
- /* @__PURE__ */ jsx(
195
- "video",
196
- {
197
- ref: videoRef,
198
- className: `${element} ${semanticClassNames.element}`,
199
- src,
200
- poster,
201
- preload: "metadata",
202
- playsInline: true,
203
- onClick: togglePlay,
204
- onDoubleClick: toggleFullscreen
205
- }
206
- ),
207
- indicator$1 && /* @__PURE__ */ jsx(
208
- "span",
209
- {
210
- className: `${indicator} ${semanticClassNames.indicator}`,
211
- "aria-hidden": true,
212
- children: indicator$1.type === "play" ? /* @__PURE__ */ jsx(PlayIcon, { size: 32 }) : /* @__PURE__ */ jsx(PauseIcon, { size: 32 })
213
- },
214
- indicator$1.key
215
- ),
216
- /* @__PURE__ */ jsxs(
217
- "div",
218
- {
219
- className: `${controls} ${semanticClassNames.controls}`,
220
- onClick: (e) => e.stopPropagation(),
221
- children: [
222
- /* @__PURE__ */ jsx(
223
- "button",
224
- {
225
- type: "button",
226
- className: `${button} ${semanticClassNames.button}`,
227
- "aria-label": playing ? "Pause" : "Play",
228
- onClick: togglePlay,
229
- children: playing ? /* @__PURE__ */ jsx(PauseIcon, {}) : /* @__PURE__ */ jsx(PlayIcon, {})
230
- }
231
- ),
232
- /* @__PURE__ */ jsx(
233
- Slider.Root,
234
- {
235
- className: `${progress} ${semanticClassNames.progress}`,
236
- min: 0,
237
- max: duration || 0,
238
- step: 0.01,
239
- value: timelineValue,
240
- onValueChange: (value) => {
241
- setDraggingTime(value);
242
- },
243
- onValueCommitted: (value) => {
244
- seekTo(value);
245
- setDraggingTime(null);
246
- if (dragWasPlayingRef.current) {
247
- play();
248
- }
249
- },
250
- children: /* @__PURE__ */ jsx(
251
- Slider.Control,
252
- {
253
- className: `${progressControl} ${semanticClassNames.progressControl}`,
254
- onPointerDown: () => {
255
- dragWasPlayingRef.current = playing;
256
- pause();
257
- setDraggingTime(currentTime);
258
- },
259
- children: /* @__PURE__ */ jsxs(
260
- Slider.Track,
261
- {
262
- className: `${progressTrack} ${semanticClassNames.progressTrack}`,
263
- children: [
264
- /* @__PURE__ */ jsx(
265
- Slider.Indicator,
266
- {
267
- className: `${progressRange} ${semanticClassNames.progressRange}`
268
- }
269
- ),
270
- /* @__PURE__ */ jsx(
271
- Slider.Thumb,
272
- {
273
- className: `${progressThumb} ${semanticClassNames.progressThumb}`,
274
- "aria-label": "Playback progress"
275
- }
276
- )
277
- ]
278
- }
279
- )
280
- }
281
- )
282
- }
283
- ),
284
- /* @__PURE__ */ jsx(
285
- "button",
286
- {
287
- type: "button",
288
- className: `${button} ${semanticClassNames.button}`,
289
- "aria-label": muted ? "Unmute" : "Mute",
290
- onClick: toggleMute,
291
- children: muted ? /* @__PURE__ */ jsx(VolumeMuteIcon, {}) : /* @__PURE__ */ jsx(VolumeIcon, {})
292
- }
293
- ),
294
- /* @__PURE__ */ jsx(
295
- "button",
296
- {
297
- type: "button",
298
- className: `${button} ${semanticClassNames.button}`,
299
- "aria-label": "Download",
300
- onClick: downloadVideo,
301
- children: isDownloading ? /* @__PURE__ */ jsx(LoadingIcon, {}) : /* @__PURE__ */ jsx(DownloadIcon, {})
302
- }
303
- ),
304
- /* @__PURE__ */ jsx(
305
- "button",
306
- {
307
- type: "button",
308
- className: `${button} ${semanticClassNames.button}`,
309
- "aria-label": isFullscreen ? "Exit fullscreen" : "Fullscreen",
310
- onClick: toggleFullscreen,
311
- children: isFullscreen ? /* @__PURE__ */ jsx(ExitFullscreenIcon, {}) : /* @__PURE__ */ jsx(FullscreenIcon, {})
312
- }
313
- )
314
- ]
315
- }
316
- )
317
- ]
318
- }
319
- ) });
320
- };
6
+ import { Video, ImageIcon, ExternalLink, Trash2 } from "lucide-react";
7
+ import { useRef, useState, useEffect, useCallback } from "react";
8
+ import { V as VideoRenderer, r as root, s as semanticClassNames, e as editPreview, a as editVideo, b as editOverlay, c as editPlaceholder, d as editTrigger, f as editPanel, g as editField, h as editFieldIcon, i as editInput, j as editActions, k as editActionButton, l as editActionButtonEnd } from "./VideoRenderer-B3RM54FU.js";
321
9
  function VideoEditRenderer(props) {
322
10
  const mode = useRendererMode();
323
11
  if (mode !== "editor") {
@@ -0,0 +1,4 @@
1
+ import { V } from "./VideoRenderer-B3RM54FU.js";
2
+ export {
3
+ V as VideoRenderer
4
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haklex/rich-renderer-video",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "Video player renderer",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,9 +22,9 @@
22
22
  "dependencies": {
23
23
  "@base-ui/react": "^1.2.0",
24
24
  "lucide-react": "^0.574.0",
25
- "@haklex/rich-editor": "0.0.39",
26
- "@haklex/rich-style-token": "0.0.39",
27
- "@haklex/rich-editor-ui": "0.0.39"
25
+ "@haklex/rich-editor": "0.0.41",
26
+ "@haklex/rich-editor-ui": "0.0.41",
27
+ "@haklex/rich-style-token": "0.0.41"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@lexical/react": "^0.41.0",