@geekapps/silo-elements-nextjs 0.2.32 → 0.2.34

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.
@@ -49,11 +49,29 @@ type VideoProps = {
49
49
  fixedHeight?: string | number;
50
50
  };
51
51
  declare function Sources(_props: SourcesProps): null;
52
+ declare namespace Sources {
53
+ var displayName: string;
54
+ }
52
55
  declare function Source(_props: SourceProps): null;
56
+ declare namespace Source {
57
+ var displayName: string;
58
+ }
53
59
  declare function Subtitles(_props: SubtitlesProps): null;
60
+ declare namespace Subtitles {
61
+ var displayName: string;
62
+ }
54
63
  declare function Subtitle(_props: SubtitleProps): null;
64
+ declare namespace Subtitle {
65
+ var displayName: string;
66
+ }
55
67
  declare function Storyboard(_props: StoryboardProps): null;
68
+ declare namespace Storyboard {
69
+ var displayName: string;
70
+ }
56
71
  declare function StoryboardFrame(_props: StoryboardFrameProps): null;
72
+ declare namespace StoryboardFrame {
73
+ var displayName: string;
74
+ }
57
75
  declare function Video({ title, description, poster, children, className, autoHideControls, defaultVolume, maxHeight, fixedHeight, }: VideoProps): react__default.JSX.Element;
58
76
  declare const VideoPlayer: typeof Video;
59
77
 
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo, useRef, useState, useCallback, useEffect } from 'react';
2
2
  import gsap from 'gsap';
3
- import { Play, Pause, VolumeX, Volume2, Captions, Settings, Minimize, Maximize } from 'lucide-react';
3
+ import { Pause, Play, VolumeX, Volume2, Captions, Settings, Minimize, Maximize } from 'lucide-react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  var AUTO_QUALITY = {
@@ -12,21 +12,27 @@ var PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2];
12
12
  function Sources(_props) {
13
13
  return null;
14
14
  }
15
+ Sources.displayName = "SiloSources";
15
16
  function Source(_props) {
16
17
  return null;
17
18
  }
19
+ Source.displayName = "SiloSource";
18
20
  function Subtitles(_props) {
19
21
  return null;
20
22
  }
23
+ Subtitles.displayName = "SiloSubtitles";
21
24
  function Subtitle(_props) {
22
25
  return null;
23
26
  }
27
+ Subtitle.displayName = "SiloSubtitle";
24
28
  function Storyboard(_props) {
25
29
  return null;
26
30
  }
31
+ Storyboard.displayName = "SiloStoryboard";
27
32
  function StoryboardFrame(_props) {
28
33
  return null;
29
34
  }
35
+ StoryboardFrame.displayName = "SiloStoryboardFrame";
30
36
  function Video({
31
37
  title,
32
38
  description,
@@ -763,8 +769,9 @@ function Video({
763
769
  /* @__PURE__ */ jsx(
764
770
  "div",
765
771
  {
766
- className: `pointer-events-none absolute inset-0 z-10 grid place-items-center transition ${isPlaying ? "opacity-0" : "opacity-100"}`,
767
- children: /* @__PURE__ */ jsx("span", { className: "grid size-10 place-items-center rounded-full bg-white/15 text-white backdrop-blur-xl ring-1 ring-white/20 @sm:size-14 @lg:size-16", children: /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-4 @sm:size-6 @lg:size-7" }) })
772
+ className: "pointer-events-none absolute inset-0 z-10 grid place-items-center",
773
+ style: { opacity: clickIcon ? 1 : 0, transition: clickIcon ? "opacity 0.08s ease-in" : "opacity 0.45s ease-out" },
774
+ children: /* @__PURE__ */ jsx("span", { className: "grid size-10 place-items-center text-white drop-shadow-[0_2px_12px_rgba(0,0,0,0.8)] @sm:size-14 @lg:size-16", children: clickIcon === "pause" ? /* @__PURE__ */ jsx(Pause, { className: "size-5 @sm:size-7 @lg:size-8" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-5 @sm:size-7 @lg:size-8" }) })
768
775
  }
769
776
  ),
770
777
  isLoading && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 z-20 grid place-items-center bg-black/10", children: /* @__PURE__ */ jsx("div", { className: "size-9 animate-spin rounded-full border-2 border-white/25 border-t-white" }) }),
@@ -785,7 +792,7 @@ function Video({
785
792
  /* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "relative z-10 px-4 pb-4 text-white", children: [
786
793
  settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
787
794
  /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-70", onClick: () => setSettingsOpen(false) }),
788
- /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-0 z-70 mb-2 w-56 overflow-hidden rounded-2xl bg-[#1c1c1e]/95 shadow-2xl backdrop-blur-xl ring-1 ring-white/10", style: { animation: "spFadeIn 0.15s ease" }, children: [
795
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-2 z-70 mb-2 overflow-hidden rounded-2xl bg-[#1c1c1e]/95 shadow-2xl backdrop-blur-xl ring-1 ring-white/10", style: { width: Math.min(224, Math.max(180, (playerWidth || 640) * 0.22)) + "px", animation: "spFadeIn 0.15s ease" }, children: [
789
796
  settingsTab === "root" && /* @__PURE__ */ jsx("div", { children: [
790
797
  { id: "quality", label: "Qualidade", value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" },
791
798
  ...parsed.subtitles.length > 0 ? [{ id: "subtitles", label: "Legendas", value: subtitleStyle.track === "off" ? "Desligado" : parsed.subtitles.find((s) => s.srclang === subtitleStyle.track)?.label ?? subtitleStyle.track }] : [],
@@ -861,7 +868,6 @@ function Video({
861
868
  const next = s.srclang === "off" ? "off" : s.srclang;
862
869
  setSubtitleMode(next);
863
870
  setSubtitleStyle((st) => ({ ...st, track: next }));
864
- setSettingsTab("root");
865
871
  },
866
872
  className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
867
873
  children: [
@@ -870,7 +876,75 @@ function Video({
870
876
  ]
871
877
  },
872
878
  s.srclang
873
- )) })
879
+ )) }),
880
+ subtitleStyle.track !== "off" && /* @__PURE__ */ jsxs(
881
+ "button",
882
+ {
883
+ type: "button",
884
+ onClick: () => setSettingsTab("subtitles-style"),
885
+ className: "flex w-full items-center justify-between gap-3 border-t border-white/8 px-4 py-3 text-sm transition hover:bg-white/8",
886
+ children: [
887
+ /* @__PURE__ */ jsx("span", { className: "text-white/60", children: "Apar\xEAncia" }),
888
+ /* @__PURE__ */ jsx("svg", { className: "size-3 opacity-50", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4.5 3l3 3-3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
889
+ ]
890
+ }
891
+ )
892
+ ] }),
893
+ settingsTab === "subtitles-style" && /* @__PURE__ */ jsxs("div", { children: [
894
+ /* @__PURE__ */ jsxs(
895
+ "button",
896
+ {
897
+ type: "button",
898
+ onClick: () => setSettingsTab("subtitles"),
899
+ className: "flex w-full items-center gap-2 border-b border-white/8 px-4 py-3 text-xs font-semibold text-white/50 transition hover:text-white",
900
+ children: [
901
+ /* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M7.5 3L4.5 6l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
902
+ "Apar\xEAncia"
903
+ ]
904
+ }
905
+ ),
906
+ /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 flex flex-col gap-3", children: [
907
+ /* @__PURE__ */ jsxs("div", { children: [
908
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Tamanho" }),
909
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
910
+ "button",
911
+ {
912
+ type: "button",
913
+ onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
914
+ className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition ${subtitleStyle.size === s ? "bg-white/20 text-white" : "text-white/45 hover:bg-white/10"}`,
915
+ children: s === "small" ? "P" : s === "medium" ? "M" : s === "large" ? "G" : "GG"
916
+ },
917
+ s
918
+ )) })
919
+ ] }),
920
+ /* @__PURE__ */ jsxs("div", { children: [
921
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Cor" }),
922
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [["white", "Branco", "#fff"], ["yellow", "Amarelo", "#facc15"], ["cyan", "Ciano", "#22d3ee"]].map(([val, label, color]) => /* @__PURE__ */ jsx(
923
+ "button",
924
+ {
925
+ type: "button",
926
+ onClick: () => setSubtitleStyle((st) => ({ ...st, color: val })),
927
+ className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition ring-1 ${subtitleStyle.color === val ? "ring-white/40" : "ring-transparent hover:ring-white/15"}`,
928
+ style: { color },
929
+ children: label
930
+ },
931
+ val
932
+ )) })
933
+ ] }),
934
+ /* @__PURE__ */ jsxs("div", { children: [
935
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Fundo" }),
936
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [["none", "Nenhum"], ["semi", "Semi"], ["solid", "S\xF3lido"]].map(([val, label]) => /* @__PURE__ */ jsx(
937
+ "button",
938
+ {
939
+ type: "button",
940
+ onClick: () => setSubtitleStyle((st) => ({ ...st, bg: val })),
941
+ className: `flex-1 rounded-lg py-1.5 text-xs font-medium transition ${subtitleStyle.bg === val ? "bg-white/20 text-white" : "text-white/45 hover:bg-white/10"}`,
942
+ children: label
943
+ },
944
+ val
945
+ )) })
946
+ ] })
947
+ ] })
874
948
  ] }),
875
949
  settingsTab === "audio" && /* @__PURE__ */ jsxs("div", { children: [
876
950
  /* @__PURE__ */ jsxs(
@@ -944,32 +1018,27 @@ function Video({
944
1018
  onPointerLeave: handleProgressPointerLeave,
945
1019
  onPointerDown: handleProgressPointerDown,
946
1020
  onPointerUp: handleProgressPointerUp,
947
- className: "group relative mb-2 h-5 cursor-pointer",
1021
+ className: "group relative mb-3 h-7 cursor-pointer",
948
1022
  children: [
949
- /* @__PURE__ */ jsxs("div", { className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/22 transition-[height] duration-150 group-hover:h-1", style: { height: isDragging ? "4px" : "2px" }, children: [
950
- /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 bg-white/30", style: { width: `${bufferedPercent}%` } }),
951
- /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 bg-white/85", style: { width: `${progressPercent}%` } })
952
- ] }),
953
- /* @__PURE__ */ jsx(
1023
+ /* @__PURE__ */ jsxs(
954
1024
  "div",
955
1025
  {
956
- className: "absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white shadow transition-[width,height] duration-100",
957
- style: {
958
- left: `${progressPercent}%`,
959
- width: isDragging ? "14px" : "0px",
960
- height: isDragging ? "14px" : "0px",
961
- opacity: isDragging ? 1 : 0
962
- }
1026
+ className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/22 transition-[height] duration-150",
1027
+ style: { height: isDragging ? "6px" : "3px" },
1028
+ children: [
1029
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 rounded-full bg-white/30", style: { width: `${bufferedPercent}%` } }),
1030
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 rounded-full bg-white/90", style: { width: `${progressPercent}%` } })
1031
+ ]
963
1032
  }
964
1033
  ),
965
1034
  /* @__PURE__ */ jsx(
966
1035
  "div",
967
1036
  {
968
- className: "pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white shadow opacity-0 transition-[width,height,opacity] duration-100 group-hover:opacity-100",
1037
+ className: "pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white shadow-md transition-[width,height] duration-100 group-hover:size-4",
969
1038
  style: {
970
1039
  left: `${progressPercent}%`,
971
- width: isDragging ? "14px" : "10px",
972
- height: isDragging ? "14px" : "10px"
1040
+ width: isDragging ? "16px" : "10px",
1041
+ height: isDragging ? "16px" : "10px"
973
1042
  }
974
1043
  }
975
1044
  )
@@ -977,57 +1046,54 @@ function Video({
977
1046
  }
978
1047
  ),
979
1048
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
980
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 @sm:gap-2", children: [
981
- /* @__PURE__ */ jsx(SeekButton, { seconds: 15, direction: "back", onClick: () => seekRelative(-15) }),
1049
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 @sm:gap-2", children: [
982
1050
  /* @__PURE__ */ jsx(
983
1051
  "button",
984
1052
  {
985
1053
  type: "button",
986
1054
  onClick: togglePlay,
987
- className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
1055
+ className: "grid size-8 place-items-center rounded-full bg-white/15 text-white backdrop-blur-sm ring-1 ring-white/15 transition hover:bg-white/25 @sm:size-9",
988
1056
  "aria-label": isPlaying ? "Pause" : "Play",
989
- children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-5 @sm:size-6" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-5 @sm:size-6" })
1057
+ children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-4 @sm:size-5" })
990
1058
  }
991
1059
  ),
992
- /* @__PURE__ */ jsx(SeekButton, { seconds: 15, direction: "forward", onClick: () => seekRelative(15) }),
993
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs font-semibold text-white/75 @sm:text-sm", children: [
994
- /* @__PURE__ */ jsx("span", { children: formatTime(currentTime) }),
995
- /* @__PURE__ */ jsx("span", { className: "text-white/35", children: "/" }),
996
- /* @__PURE__ */ jsxs("span", { className: "text-white/50", children: [
997
- "-",
998
- formatTime(Math.max(0, duration - currentTime))
999
- ] })
1060
+ /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-medium tabular-nums text-white/80", children: [
1061
+ formatTime(currentTime),
1062
+ /* @__PURE__ */ jsx("span", { className: "text-white/30", children: "/" }),
1063
+ /* @__PURE__ */ jsx("span", { className: "text-white/45", children: formatTime(duration) })
1000
1064
  ] })
1001
1065
  ] }),
1002
1066
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 @sm:gap-1", children: [
1003
- /* @__PURE__ */ jsx(
1004
- "button",
1005
- {
1006
- type: "button",
1007
- onClick: () => setIsMuted((value) => !value),
1008
- className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
1009
- "aria-label": isMuted ? "Unmute" : "Mute",
1010
- children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-5" })
1011
- }
1012
- ),
1013
- /* @__PURE__ */ jsx(
1014
- "input",
1015
- {
1016
- type: "range",
1017
- min: "0",
1018
- max: "1",
1019
- step: "0.01",
1020
- value: isMuted ? 0 : volume,
1021
- onChange: (event) => {
1022
- const nextVolume = Number(event.target.value);
1023
- setVolume(nextVolume);
1024
- setIsMuted(nextVolume === 0);
1025
- },
1026
- className: "hidden h-1 w-14 accent-white @md:block @md:w-20",
1027
- "aria-label": "Audio level"
1028
- }
1029
- ),
1030
- /* @__PURE__ */ jsx("div", { className: "mx-0.5 hidden h-4 w-px bg-white/20 @md:mx-1 @md:block" }),
1067
+ /* @__PURE__ */ jsxs("div", { className: "group flex items-center", children: [
1068
+ /* @__PURE__ */ jsx(
1069
+ "button",
1070
+ {
1071
+ type: "button",
1072
+ onClick: () => setIsMuted((value) => !value),
1073
+ className: "grid size-8 place-items-center text-white/70 transition hover:text-white @sm:size-9",
1074
+ "aria-label": isMuted ? "Unmute" : "Mute",
1075
+ children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-5" })
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ jsx("div", { className: "w-0 overflow-hidden transition-all duration-200 group-hover:w-16 @md:group-hover:w-20", children: /* @__PURE__ */ jsx(
1079
+ "input",
1080
+ {
1081
+ type: "range",
1082
+ min: "0",
1083
+ max: "1",
1084
+ step: "0.01",
1085
+ value: isMuted ? 0 : volume,
1086
+ onChange: (event) => {
1087
+ const nextVolume = Number(event.target.value);
1088
+ setVolume(nextVolume);
1089
+ setIsMuted(nextVolume === 0);
1090
+ },
1091
+ className: "h-1 w-14 accent-white @md:w-20",
1092
+ "aria-label": "Audio level"
1093
+ }
1094
+ ) })
1095
+ ] }),
1096
+ /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" }),
1031
1097
  parsed.subtitles.length > 0 && /* @__PURE__ */ jsx(
1032
1098
  "button",
1033
1099
  {
@@ -1067,14 +1133,6 @@ function Video({
1067
1133
  ]
1068
1134
  }
1069
1135
  ),
1070
- /* @__PURE__ */ jsx(
1071
- "div",
1072
- {
1073
- className: "pointer-events-none absolute inset-0 z-50 grid place-items-center",
1074
- style: { opacity: clickIcon ? 1 : 0, transition: clickIcon ? "opacity 0.08s ease-in" : "opacity 0.45s ease-out" },
1075
- children: /* @__PURE__ */ jsx("span", { className: "grid size-10 place-items-center rounded-full bg-black/40 text-white backdrop-blur-sm ring-1 ring-white/20 @sm:size-14 @lg:size-16", children: clickIcon === "pause" ? /* @__PURE__ */ jsx(Pause, { className: "size-4 @sm:size-6 @lg:size-7" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-4 @sm:size-6 @lg:size-7" }) })
1076
- }
1077
- ),
1078
1136
  preview && (() => {
1079
1137
  const srcW = preview.cue.w ?? 160;
1080
1138
  const srcH = preview.cue.h ?? 90;
@@ -1140,70 +1198,41 @@ function Video({
1140
1198
  );
1141
1199
  }
1142
1200
  var VideoPlayer = Video;
1143
- function SeekButton({ seconds, direction, onClick }) {
1144
- return /* @__PURE__ */ jsx(
1145
- "button",
1146
- {
1147
- type: "button",
1148
- onClick,
1149
- className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
1150
- "aria-label": `${direction === "back" ? "Rewind" : "Forward"} ${seconds} seconds`,
1151
- children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 36 36", fill: "none", className: "size-7 @sm:size-8", children: [
1152
- /* @__PURE__ */ jsx(
1153
- "path",
1154
- {
1155
- d: direction === "back" ? "M18 6C11.373 6 6 11.373 6 18s5.373 12 12 12 12-5.373 12-12" : "M18 6C24.627 6 30 11.373 30 18S24.627 30 18 30 6 24.627 6 18",
1156
- stroke: "currentColor",
1157
- strokeWidth: "2",
1158
- strokeLinecap: "round"
1159
- }
1160
- ),
1161
- /* @__PURE__ */ jsx(
1162
- "path",
1163
- {
1164
- d: direction === "back" ? "M18 6l-4 4 4 4" : "M18 6l4 4-4 4",
1165
- stroke: "currentColor",
1166
- strokeWidth: "2",
1167
- strokeLinecap: "round",
1168
- strokeLinejoin: "round"
1169
- }
1170
- ),
1171
- /* @__PURE__ */ jsx("text", { x: "18", y: "22", textAnchor: "middle", fill: "currentColor", fontSize: "9", fontWeight: "600", fontFamily: "system-ui", children: seconds })
1172
- ] })
1173
- }
1174
- );
1175
- }
1176
1201
  function parseVideoChildren(children) {
1177
1202
  const parsed = {
1178
1203
  sources: [],
1179
1204
  subtitles: []
1180
1205
  };
1206
+ function isType(child, fn) {
1207
+ if (child.type === fn) return true;
1208
+ return child.type?.displayName === fn.displayName && !!fn.displayName;
1209
+ }
1181
1210
  React.Children.forEach(children, (child) => {
1182
1211
  if (!React.isValidElement(child)) return;
1183
- if (child.type === Sources) {
1212
+ if (isType(child, Sources)) {
1184
1213
  const element = child;
1185
1214
  React.Children.forEach(element.props.children, (sourceChild) => {
1186
1215
  if (!React.isValidElement(sourceChild)) return;
1187
- if (sourceChild.type !== Source) return;
1216
+ if (!isType(sourceChild, Source)) return;
1188
1217
  const sourceElement = sourceChild;
1189
1218
  parsed.sources.push(sourceElement.props);
1190
1219
  });
1191
1220
  }
1192
- if (child.type === Subtitles) {
1221
+ if (isType(child, Subtitles)) {
1193
1222
  const element = child;
1194
1223
  React.Children.forEach(element.props.children, (subtitleChild) => {
1195
1224
  if (!React.isValidElement(subtitleChild)) return;
1196
- if (subtitleChild.type !== Subtitle) return;
1225
+ if (!isType(subtitleChild, Subtitle)) return;
1197
1226
  const subtitleElement = subtitleChild;
1198
1227
  parsed.subtitles.push(subtitleElement.props);
1199
1228
  });
1200
1229
  }
1201
- if (child.type === Storyboard) {
1230
+ if (isType(child, Storyboard)) {
1202
1231
  const element = child;
1203
1232
  const frames = [];
1204
1233
  React.Children.forEach(element.props.children, (frameChild) => {
1205
1234
  if (!React.isValidElement(frameChild)) return;
1206
- if (frameChild.type !== StoryboardFrame) return;
1235
+ if (!isType(frameChild, StoryboardFrame)) return;
1207
1236
  const frameElement = frameChild;
1208
1237
  frames.push(frameElement.props);
1209
1238
  });
@@ -1277,18 +1306,15 @@ function parseVttTimestamp(value) {
1277
1306
  return Number(normalized) || 0;
1278
1307
  }
1279
1308
  function formatTime(seconds) {
1280
- if (!Number.isFinite(seconds)) return "00:00";
1309
+ if (!Number.isFinite(seconds)) return "0:00";
1281
1310
  const safeSeconds = Math.max(0, Math.floor(seconds));
1282
1311
  const hours = Math.floor(safeSeconds / 3600);
1283
1312
  const minutes = Math.floor(safeSeconds % 3600 / 60);
1284
1313
  const secs = safeSeconds % 60;
1285
1314
  if (hours > 0) {
1286
- return `${hours}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(
1287
- 2,
1288
- "0"
1289
- )}`;
1315
+ return `${hours}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
1290
1316
  }
1291
- return `${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
1317
+ return `${minutes}:${String(secs).padStart(2, "0")}`;
1292
1318
  }
1293
1319
 
1294
1320
  export { Source, Sources, Storyboard, StoryboardFrame, Subtitle, Subtitles, Video, VideoPlayer };