react-helios 2.0.0 → 2.1.0

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/dist/styles.css CHANGED
@@ -379,15 +379,9 @@
379
379
  border-radius: 2px;
380
380
  }
381
381
 
382
- /* ─── Hidden preview video ───────────────────────────────────────────────── */
383
- .previewVideo {
384
- display: none;
385
- }
386
-
387
382
  /* ─── Thumbnail tooltip ──────────────────────────────────────────────────── */
388
383
  .previewTooltip {
389
384
  position: absolute;
390
- /* Sits above the container; bottom 100% + a small gap */
391
385
  bottom: calc(100% + 6px);
392
386
  transform: translateX(-50%);
393
387
  pointer-events: none;
@@ -396,12 +390,20 @@
396
390
  border-radius: 4px;
397
391
  overflow: hidden;
398
392
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
393
+ /* Shown/hidden imperatively — default hidden until mouseenter */
394
+ display: none;
399
395
  }
400
396
 
401
- .previewCanvas {
397
+ /*
398
+ * VTT sprite-sheet thumbnail cell.
399
+ * Dimensions and background-position are set imperatively from VTT cue data.
400
+ * background-size is kept auto so the full sprite sheet renders at natural
401
+ * resolution and background-position clips to the correct cell.
402
+ */
403
+ .previewThumbnail {
402
404
  display: block;
403
- width: 160px;
404
- height: 90px;
405
+ background-repeat: no-repeat;
406
+ background-size: auto;
405
407
  }
406
408
 
407
409
  .previewTime {
@@ -411,6 +413,8 @@
411
413
  color: #fff;
412
414
  text-align: center;
413
415
  background-color: rgba(0, 0, 0, 0.7);
416
+ /* Show a minimum width when there is no thumbnail above it */
417
+ min-width: 52px;
414
418
  }
415
419
 
416
420
  /* ─── Track background ───────────────────────────────────────────────────── */
@@ -453,6 +457,7 @@
453
457
  }
454
458
 
455
459
  /* ─── Hover position indicator (thin white line) ────────────────────────── */
460
+ /* Shown/hidden imperatively — default hidden until mouseenter */
456
461
  .hoverIndicator {
457
462
  position: absolute;
458
463
  top: 50%;
@@ -461,6 +466,7 @@
461
466
  height: 100%;
462
467
  background-color: rgba(255, 255, 255, 0.8);
463
468
  pointer-events: none;
469
+ display: none;
464
470
  }
465
471
 
466
472
  /* ─── Scrub handle ───────────────────────────────────────────────────────── */
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-helios",
3
- "version": "2.0.0",
4
- "description": "Production-grade React video player with HLS, quality selection, live streams, subtitles, and thumbnail preview",
3
+ "version": "2.1.0",
4
+ "description": "Production-grade React video player with HLS, quality selection, live streams, subtitles, and VTT sprite thumbnail preview",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -16,10 +16,13 @@
16
16
  "import": "./dist/index.mjs",
17
17
  "require": "./dist/index.js"
18
18
  },
19
- "./styles": "./dist/styles.css"
19
+ "./styles": {
20
+ "types": "./dist/styles.d.ts",
21
+ "default": "./dist/styles.css"
22
+ }
20
23
  },
21
24
  "scripts": {
22
- "build": "tsup",
25
+ "build": "tsup && node -e \"require('fs').writeFileSync('dist/styles.d.ts', 'export {};\\n');\"",
23
26
  "dev": "tsup --watch",
24
27
  "typecheck": "tsc --noEmit",
25
28
  "prepublishOnly": "npm run build"
@@ -39,7 +42,10 @@
39
42
  "captions",
40
43
  "typescript",
41
44
  "nextjs",
42
- "picture-in-picture"
45
+ "picture-in-picture",
46
+ "vtt",
47
+ "sprite-sheet",
48
+ "thumbnail-preview"
43
49
  ],
44
50
  "author": "Sanish Manandhar <mail.sanishmanandhar@gmail.com>",
45
51
  "license": "MIT",
package/dist/index.css DELETED
@@ -1,2 +0,0 @@
1
- .controlButton{background:none;border:none;color:#fff;cursor:pointer;padding:10px;min-width:40px;min-height:40px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:opacity .15s,background-color .15s,transform .1s;flex-shrink:0}.controlButton:hover{background-color:#ffffff1f;opacity:1}.controlButton:active{transform:scale(.92)}.controlButton svg{width:20px;height:20px;pointer-events:none}@media(max-width:480px){.controlButton{padding:8px;min-width:36px;min-height:36px}}.volumeContainer{position:relative;display:flex;align-items:center}.volumeSlider{width:80px;cursor:pointer;-webkit-appearance:none;appearance:none;background:#ffffff4d;border-radius:2px;height:4px;outline:none;transition:width .15s;flex-shrink:0}.volumeSlider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:12px;height:12px;background:#fff;border-radius:50%;cursor:pointer;box-shadow:0 1px 4px #0006}.volumeSlider::-moz-range-thumb{width:12px;height:12px;background:#fff;border-radius:50%;cursor:pointer;border:none;box-shadow:0 1px 4px #0006}.timeDisplay{color:#fff;font-size:13px;font-weight:500;user-select:none;white-space:nowrap;padding:0 4px;letter-spacing:.01em}.settingsContainer{position:relative}.settingsDropdown{position:absolute;bottom:calc(100% + 8px);right:0;background-color:#0f0f0ff2;border-radius:6px;padding:6px;min-width:150px;z-index:30;box-shadow:0 4px 24px #0009;backdrop-filter:blur(8px)}.settingsTabs{display:flex;border-bottom:1px solid rgba(255,255,255,.12);margin-bottom:4px}.settingsTab{flex:1;background:none;border:none;color:#fff9;cursor:pointer;font-size:12px;font-weight:600;padding:6px 0;letter-spacing:.04em;border-bottom:2px solid transparent;transition:color .15s,border-color .15s;text-transform:uppercase}.settingsTab.active{color:#fff;border-bottom-color:#3b82f6}.settingsTab:hover:not(.active){color:#ffffffe6}.settingsPanelLabel{color:#ffffff80;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:4px 8px 2px}.settingsOption{display:flex;align-items:center;justify-content:space-between;width:100%;padding:7px 10px;background:none;border:none;color:#ffffffd9;cursor:pointer;text-align:left;border-radius:4px;font-size:13px;transition:background-color .15s}.settingsOption:hover{background-color:#ffffff1a;color:#fff}.settingsOption.active{color:#60a5fa;font-weight:600}.settingsOptionBadge{font-size:10px;color:#fff6;margin-left:8px;flex-shrink:0}.progressContainer{position:relative;width:100%;padding:10px 0;cursor:pointer;box-sizing:content-box}.progressContainer:focus{outline:none}.progressContainer:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}.previewVideo{display:none}.previewTooltip{position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);pointer-events:none;z-index:20;background-color:#000;border-radius:4px;overflow:hidden;box-shadow:0 4px 16px #00000080}.previewCanvas{display:block;width:160px;height:90px}.previewTime{padding:3px 8px;font-size:11px;font-weight:600;color:#fff;text-align:center;background-color:#000000b3}.progressBackground{position:relative;width:100%;height:4px;background-color:#ffffff40;border-radius:2px;overflow:hidden;transition:height .15s;will-change:height}.progressContainer:hover .progressBackground{height:6px}.bufferedSegment{position:absolute;top:0;height:100%;background-color:#ffffff73;border-radius:2px}.progressFilled{position:absolute;top:0;left:0;height:100%;background-color:#3b82f6;border-radius:2px;will-change:width}.hoverIndicator{position:absolute;top:50%;transform:translate(-50%,-50%);width:2px;height:100%;background-color:#fffc;pointer-events:none}.scrubHandle{position:absolute;top:50%;transform:translate(-50%,-50%);width:14px;height:14px;background-color:#fff;border-radius:50%;box-shadow:0 1px 6px #00000080;pointer-events:none;transition:transform .12s,opacity .12s;opacity:0;z-index:2;will-change:transform,opacity}.progressContainer:hover .scrubHandle,.scrubHandle.dragging{opacity:1}.scrubHandle.dragging{transform:translate(-50%,-50%) scale(1.25);transition:none}
2
- /*# sourceMappingURL=index.css.map */
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/styles/ControlElements.css","../src/styles/ProgressBar.css"],"sourcesContent":["/* ─── Control button base ────────────────────────────────────────────────── */\n.controlButton {\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n padding: 10px;\n min-width: 40px;\n min-height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: opacity 0.15s, background-color 0.15s, transform 0.1s;\n flex-shrink: 0;\n}\n\n.controlButton:hover {\n background-color: rgba(255, 255, 255, 0.12);\n opacity: 1;\n}\n\n.controlButton:active {\n transform: scale(0.92);\n}\n\n.controlButton svg {\n width: 20px;\n height: 20px;\n pointer-events: none;\n}\n\n@media (max-width: 480px) {\n .controlButton {\n padding: 8px;\n min-width: 36px;\n min-height: 36px;\n }\n}\n\n/* ─── Volume control ─────────────────────────────────────────────────────── */\n.volumeContainer {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.volumeSlider {\n width: 80px;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n height: 4px;\n outline: none;\n transition: width 0.15s;\n flex-shrink: 0;\n}\n\n.volumeSlider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 12px;\n height: 12px;\n background: #fff;\n border-radius: 50%;\n cursor: pointer;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);\n}\n\n.volumeSlider::-moz-range-thumb {\n width: 12px;\n height: 12px;\n background: #fff;\n border-radius: 50%;\n cursor: pointer;\n border: none;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);\n}\n\n/* ─── Time display ───────────────────────────────────────────────────────── */\n.timeDisplay {\n color: #fff;\n font-size: 13px;\n font-weight: 500;\n user-select: none;\n white-space: nowrap;\n padding: 0 4px;\n letter-spacing: 0.01em;\n}\n\n/* ─── Settings menu ──────────────────────────────────────────────────────── */\n.settingsContainer {\n position: relative;\n}\n\n.settingsDropdown {\n position: absolute;\n bottom: calc(100% + 8px);\n right: 0;\n background-color: rgba(15, 15, 15, 0.95);\n border-radius: 6px;\n padding: 6px;\n min-width: 150px;\n z-index: 30;\n box-shadow: 0 4px 24px rgba(0, 0, 0, 0.6);\n backdrop-filter: blur(8px);\n}\n\n/* Tabs (Speed / Quality) */\n.settingsTabs {\n display: flex;\n border-bottom: 1px solid rgba(255, 255, 255, 0.12);\n margin-bottom: 4px;\n}\n\n.settingsTab {\n flex: 1;\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.6);\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n padding: 6px 0;\n letter-spacing: 0.04em;\n border-bottom: 2px solid transparent;\n transition: color 0.15s, border-color 0.15s;\n text-transform: uppercase;\n}\n\n.settingsTab.active {\n color: #fff;\n border-bottom-color: #3b82f6;\n}\n\n.settingsTab:hover:not(.active) {\n color: rgba(255, 255, 255, 0.9);\n}\n\n/* Panel section label */\n.settingsPanelLabel {\n color: rgba(255, 255, 255, 0.5);\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n padding: 4px 8px 2px;\n}\n\n/* Option rows */\n.settingsOption {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 7px 10px;\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.85);\n cursor: pointer;\n text-align: left;\n border-radius: 4px;\n font-size: 13px;\n transition: background-color 0.15s;\n}\n\n.settingsOption:hover {\n background-color: rgba(255, 255, 255, 0.1);\n color: #fff;\n}\n\n.settingsOption.active {\n color: #60a5fa;\n font-weight: 600;\n}\n\n.settingsOptionBadge {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.4);\n margin-left: 8px;\n flex-shrink: 0;\n}\n","/* ─── Progress bar container ─────────────────────────────────────────────── */\n.progressContainer {\n position: relative;\n width: 100%;\n /* Tall hit area so scrub feels easy to grab on touch and mouse */\n padding: 10px 0;\n cursor: pointer;\n /* Expand the clickable zone without affecting layout neighbours */\n box-sizing: content-box;\n}\n\n.progressContainer:focus {\n outline: none;\n}\n\n.progressContainer:focus-visible {\n outline: 2px solid #60a5fa;\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n/* ─── Hidden preview video ───────────────────────────────────────────────── */\n.previewVideo {\n display: none;\n}\n\n/* ─── Thumbnail tooltip ──────────────────────────────────────────────────── */\n.previewTooltip {\n position: absolute;\n /* Sits above the container; bottom 100% + a small gap */\n bottom: calc(100% + 6px);\n transform: translateX(-50%);\n pointer-events: none;\n z-index: 20;\n background-color: #000;\n border-radius: 4px;\n overflow: hidden;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);\n}\n\n.previewCanvas {\n display: block;\n width: 160px;\n height: 90px;\n}\n\n.previewTime {\n padding: 3px 8px;\n font-size: 11px;\n font-weight: 600;\n color: #fff;\n text-align: center;\n background-color: rgba(0, 0, 0, 0.7);\n}\n\n/* ─── Track background ───────────────────────────────────────────────────── */\n.progressBackground {\n position: relative;\n width: 100%;\n height: 4px;\n background-color: rgba(255, 255, 255, 0.25);\n border-radius: 2px;\n /* Keep overflow:hidden for buffered / filled bars ONLY.\n The scrub handle must live OUTSIDE this element. */\n overflow: hidden;\n transition: height 0.15s;\n will-change: height;\n}\n\n/* Grow the track on hover for a \"YouTube-style\" feel */\n.progressContainer:hover .progressBackground {\n height: 6px;\n}\n\n/* ─── Buffered range indicator ───────────────────────────────────────────── */\n.bufferedSegment {\n position: absolute;\n top: 0;\n height: 100%;\n background-color: rgba(255, 255, 255, 0.45);\n border-radius: 2px;\n}\n\n/* ─── Played progress fill ───────────────────────────────────────────────── */\n.progressFilled {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background-color: #3b82f6;\n border-radius: 2px;\n will-change: width;\n}\n\n/* ─── Hover position indicator (thin white line) ────────────────────────── */\n.hoverIndicator {\n position: absolute;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 2px;\n height: 100%;\n background-color: rgba(255, 255, 255, 0.8);\n pointer-events: none;\n}\n\n/* ─── Scrub handle ───────────────────────────────────────────────────────── */\n/*\n * The handle is a SIBLING of .progressBackground (outside overflow:hidden).\n * It is positioned absolutely within .progressContainer, which provides\n * the full padded height. `top: 50%` centers it on the container mid-line,\n * which aligns with the track regardless of the container's padding.\n *\n * Fix: previously the handle was inside overflow:hidden and only a tiny\n * sliver was visible on the 4px-tall track.\n */\n.scrubHandle {\n position: absolute;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 14px;\n height: 14px;\n background-color: #fff;\n border-radius: 50%;\n box-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);\n pointer-events: none;\n transition: transform 0.12s, opacity 0.12s;\n /* Hidden by default; shown on container hover */\n opacity: 0;\n z-index: 2;\n will-change: transform, opacity;\n}\n\n.progressContainer:hover .scrubHandle,\n.scrubHandle.dragging {\n opacity: 1;\n}\n\n.scrubHandle.dragging {\n transform: translate(-50%, -50%) scale(1.25);\n transition: none;\n}\n"],"mappings":"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","names":[]}