@geekapps/silo-elements-nextjs 0.2.32 → 0.2.33

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.
@@ -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 = {
@@ -763,8 +763,9 @@ function Video({
763
763
  /* @__PURE__ */ jsx(
764
764
  "div",
765
765
  {
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" }) })
766
+ className: "pointer-events-none absolute inset-0 z-10 grid place-items-center",
767
+ style: { opacity: clickIcon ? 1 : 0, transition: clickIcon ? "opacity 0.08s ease-in" : "opacity 0.45s ease-out" },
768
+ 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
769
  }
769
770
  ),
770
771
  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 +786,7 @@ function Video({
785
786
  /* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "relative z-10 px-4 pb-4 text-white", children: [
786
787
  settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
787
788
  /* @__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: [
789
+ /* @__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
790
  settingsTab === "root" && /* @__PURE__ */ jsx("div", { children: [
790
791
  { id: "quality", label: "Qualidade", value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" },
791
792
  ...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 +862,6 @@ function Video({
861
862
  const next = s.srclang === "off" ? "off" : s.srclang;
862
863
  setSubtitleMode(next);
863
864
  setSubtitleStyle((st) => ({ ...st, track: next }));
864
- setSettingsTab("root");
865
865
  },
866
866
  className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
867
867
  children: [
@@ -870,7 +870,75 @@ function Video({
870
870
  ]
871
871
  },
872
872
  s.srclang
873
- )) })
873
+ )) }),
874
+ subtitleStyle.track !== "off" && /* @__PURE__ */ jsxs(
875
+ "button",
876
+ {
877
+ type: "button",
878
+ onClick: () => setSettingsTab("subtitles-style"),
879
+ 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",
880
+ children: [
881
+ /* @__PURE__ */ jsx("span", { className: "text-white/60", children: "Apar\xEAncia" }),
882
+ /* @__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" }) })
883
+ ]
884
+ }
885
+ )
886
+ ] }),
887
+ settingsTab === "subtitles-style" && /* @__PURE__ */ jsxs("div", { children: [
888
+ /* @__PURE__ */ jsxs(
889
+ "button",
890
+ {
891
+ type: "button",
892
+ onClick: () => setSettingsTab("subtitles"),
893
+ 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",
894
+ children: [
895
+ /* @__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" }) }),
896
+ "Apar\xEAncia"
897
+ ]
898
+ }
899
+ ),
900
+ /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 flex flex-col gap-3", children: [
901
+ /* @__PURE__ */ jsxs("div", { children: [
902
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Tamanho" }),
903
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
904
+ "button",
905
+ {
906
+ type: "button",
907
+ onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
908
+ 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"}`,
909
+ children: s === "small" ? "P" : s === "medium" ? "M" : s === "large" ? "G" : "GG"
910
+ },
911
+ s
912
+ )) })
913
+ ] }),
914
+ /* @__PURE__ */ jsxs("div", { children: [
915
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Cor" }),
916
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [["white", "Branco", "#fff"], ["yellow", "Amarelo", "#facc15"], ["cyan", "Ciano", "#22d3ee"]].map(([val, label, color]) => /* @__PURE__ */ jsx(
917
+ "button",
918
+ {
919
+ type: "button",
920
+ onClick: () => setSubtitleStyle((st) => ({ ...st, color: val })),
921
+ 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"}`,
922
+ style: { color },
923
+ children: label
924
+ },
925
+ val
926
+ )) })
927
+ ] }),
928
+ /* @__PURE__ */ jsxs("div", { children: [
929
+ /* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold text-white/40 uppercase tracking-wide", children: "Fundo" }),
930
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5", children: [["none", "Nenhum"], ["semi", "Semi"], ["solid", "S\xF3lido"]].map(([val, label]) => /* @__PURE__ */ jsx(
931
+ "button",
932
+ {
933
+ type: "button",
934
+ onClick: () => setSubtitleStyle((st) => ({ ...st, bg: val })),
935
+ 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"}`,
936
+ children: label
937
+ },
938
+ val
939
+ )) })
940
+ ] })
941
+ ] })
874
942
  ] }),
875
943
  settingsTab === "audio" && /* @__PURE__ */ jsxs("div", { children: [
876
944
  /* @__PURE__ */ jsxs(
@@ -944,32 +1012,27 @@ function Video({
944
1012
  onPointerLeave: handleProgressPointerLeave,
945
1013
  onPointerDown: handleProgressPointerDown,
946
1014
  onPointerUp: handleProgressPointerUp,
947
- className: "group relative mb-2 h-5 cursor-pointer",
1015
+ className: "group relative mb-3 h-7 cursor-pointer",
948
1016
  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(
1017
+ /* @__PURE__ */ jsxs(
954
1018
  "div",
955
1019
  {
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
- }
1020
+ className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/22 transition-[height] duration-150",
1021
+ style: { height: isDragging ? "6px" : "3px" },
1022
+ children: [
1023
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 rounded-full bg-white/30", style: { width: `${bufferedPercent}%` } }),
1024
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 rounded-full bg-white/90", style: { width: `${progressPercent}%` } })
1025
+ ]
963
1026
  }
964
1027
  ),
965
1028
  /* @__PURE__ */ jsx(
966
1029
  "div",
967
1030
  {
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",
1031
+ 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
1032
  style: {
970
1033
  left: `${progressPercent}%`,
971
- width: isDragging ? "14px" : "10px",
972
- height: isDragging ? "14px" : "10px"
1034
+ width: isDragging ? "16px" : "10px",
1035
+ height: isDragging ? "16px" : "10px"
973
1036
  }
974
1037
  }
975
1038
  )
@@ -977,57 +1040,54 @@ function Video({
977
1040
  }
978
1041
  ),
979
1042
  /* @__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) }),
1043
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 @sm:gap-2", children: [
982
1044
  /* @__PURE__ */ jsx(
983
1045
  "button",
984
1046
  {
985
1047
  type: "button",
986
1048
  onClick: togglePlay,
987
- className: "grid size-8 place-items-center text-white transition hover:scale-110 hover:text-white/80 @sm:size-10",
1049
+ 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
1050
  "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" })
1051
+ children: isPlaying ? /* @__PURE__ */ jsx(Pause, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Play, { className: "ml-0.5 size-4 @sm:size-5" })
990
1052
  }
991
1053
  ),
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
- ] })
1054
+ /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-medium tabular-nums text-white/80", children: [
1055
+ formatTime(currentTime),
1056
+ /* @__PURE__ */ jsx("span", { className: "text-white/30", children: "/" }),
1057
+ /* @__PURE__ */ jsx("span", { className: "text-white/45", children: formatTime(duration) })
1000
1058
  ] })
1001
1059
  ] }),
1002
1060
  /* @__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" }),
1061
+ /* @__PURE__ */ jsxs("div", { className: "group flex items-center", children: [
1062
+ /* @__PURE__ */ jsx(
1063
+ "button",
1064
+ {
1065
+ type: "button",
1066
+ onClick: () => setIsMuted((value) => !value),
1067
+ className: "grid size-8 place-items-center text-white/70 transition hover:text-white @sm:size-9",
1068
+ "aria-label": isMuted ? "Unmute" : "Mute",
1069
+ children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-5" })
1070
+ }
1071
+ ),
1072
+ /* @__PURE__ */ jsx("div", { className: "w-0 overflow-hidden transition-all duration-200 group-hover:w-16 @md:group-hover:w-20", children: /* @__PURE__ */ jsx(
1073
+ "input",
1074
+ {
1075
+ type: "range",
1076
+ min: "0",
1077
+ max: "1",
1078
+ step: "0.01",
1079
+ value: isMuted ? 0 : volume,
1080
+ onChange: (event) => {
1081
+ const nextVolume = Number(event.target.value);
1082
+ setVolume(nextVolume);
1083
+ setIsMuted(nextVolume === 0);
1084
+ },
1085
+ className: "h-1 w-14 accent-white @md:w-20",
1086
+ "aria-label": "Audio level"
1087
+ }
1088
+ ) })
1089
+ ] }),
1090
+ /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" }),
1031
1091
  parsed.subtitles.length > 0 && /* @__PURE__ */ jsx(
1032
1092
  "button",
1033
1093
  {
@@ -1067,14 +1127,6 @@ function Video({
1067
1127
  ]
1068
1128
  }
1069
1129
  ),
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
1130
  preview && (() => {
1079
1131
  const srcW = preview.cue.w ?? 160;
1080
1132
  const srcH = preview.cue.h ?? 90;
@@ -1140,39 +1192,6 @@ function Video({
1140
1192
  );
1141
1193
  }
1142
1194
  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
1195
  function parseVideoChildren(children) {
1177
1196
  const parsed = {
1178
1197
  sources: [],
@@ -1277,18 +1296,15 @@ function parseVttTimestamp(value) {
1277
1296
  return Number(normalized) || 0;
1278
1297
  }
1279
1298
  function formatTime(seconds) {
1280
- if (!Number.isFinite(seconds)) return "00:00";
1299
+ if (!Number.isFinite(seconds)) return "0:00";
1281
1300
  const safeSeconds = Math.max(0, Math.floor(seconds));
1282
1301
  const hours = Math.floor(safeSeconds / 3600);
1283
1302
  const minutes = Math.floor(safeSeconds % 3600 / 60);
1284
1303
  const secs = safeSeconds % 60;
1285
1304
  if (hours > 0) {
1286
- return `${hours}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(
1287
- 2,
1288
- "0"
1289
- )}`;
1305
+ return `${hours}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
1290
1306
  }
1291
- return `${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
1307
+ return `${minutes}:${String(secs).padStart(2, "0")}`;
1292
1308
  }
1293
1309
 
1294
1310
  export { Source, Sources, Storyboard, StoryboardFrame, Subtitle, Subtitles, Video, VideoPlayer };