itube-modern-player 0.2.3 → 0.3.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/player.d.ts CHANGED
@@ -92,6 +92,11 @@ export declare class Player {
92
92
  get playlist(): VideoSource[];
93
93
  get index(): number;
94
94
  get source(): VideoSource | null;
95
+ /**
96
+ * The item that `next()` would play in linear order (for the next-up preview).
97
+ * `null` in shuffle mode (the pick is random) or when there is no next item.
98
+ */
99
+ get nextSource(): VideoSource | null;
95
100
  get hasPlaylist(): boolean;
96
101
  get hasNext(): boolean;
97
102
  get hasPrevious(): boolean;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .imp-player{--imp-accent: #e53935;--imp-bg: #000;--imp-text: #fff;--imp-control-bg: rgba(20, 20, 20, .85);--imp-track: rgba(255, 255, 255, .25);--imp-track-buffered: rgba(255, 255, 255, .35);--imp-radius: 8px;--imp-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--imp-controls-height: 48px;--imp-transition: .18s ease;position:relative;width:100%;aspect-ratio:16 / 9;background:var(--imp-bg);color:var(--imp-text);font-family:var(--imp-font);font-size:14px;line-height:1.4;overflow:hidden;border-radius:var(--imp-radius);outline:none;user-select:none;-webkit-user-select:none;container-type:inline-size}.imp-player--fullscreen{border-radius:0}.imp-player [hidden],.imp-ad [hidden]{display:none!important}.imp-video{width:100%;height:100%;display:block;object-fit:contain}.imp-layer{position:absolute;inset:0;display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0,1fr);grid-template-areas:"top" "middle" "bottom";pointer-events:none}.imp-layer__middle{grid-area:middle;display:flex;align-items:center;justify-content:center}.imp-center-controls{position:absolute;inset:0;align-items:center;justify-content:center;gap:16px;pointer-events:none;transition:opacity var(--imp-transition)}.imp-player--idle .imp-center-controls{opacity:0;pointer-events:none}.imp-player--idle .imp-center-controls *,.imp-player--idle .imp-layer__bottom *{pointer-events:none}.imp-center-btn{pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;padding:10px;border:0;border-radius:50%;background:#00000073;color:#fff;cursor:pointer;transition:background var(--imp-transition),transform var(--imp-transition)}.imp-center-btn svg{width:100%;height:100%}.imp-center-btn--play{width:56px;height:56px;padding:14px;background:var(--imp-accent)}.imp-center-btn:hover:not(:disabled){background:#0009}.imp-center-btn--play:hover:not(:disabled){background:var(--imp-accent)}.imp-center-btn:active:not(:disabled){transform:scale(.9)}.imp-center-btn:disabled{opacity:.35;cursor:default}.imp-layer__bottom{grid-area:bottom;display:flex;flex-direction:column;background:linear-gradient(transparent,#000000b3);padding:24px 12px 8px;opacity:1;transition:opacity var(--imp-transition)}.imp-player--idle .imp-layer__bottom{opacity:0;pointer-events:none}.imp-player--idle{cursor:none}.imp-btn{pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;padding:6px;border:0;border-radius:6px;background:transparent;color:inherit;cursor:pointer;transition:background var(--imp-transition),transform var(--imp-transition)}.imp-btn svg{width:100%;height:100%}.imp-btn:hover:not(:disabled){background:#ffffff26}.imp-btn:focus-visible{outline:2px solid var(--imp-accent);outline-offset:1px}.imp-btn:disabled{opacity:.35;cursor:default}.imp-btn--active{color:var(--imp-accent)}.imp-btn--like.imp-btn--active{color:var(--imp-like, forestgreen)}.imp-btn--dislike.imp-btn--active{color:var(--imp-dislike, #e53935)}.imp-action{position:relative;display:inline-flex}.imp-count-tooltip{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%) scale(.9);padding:3px 7px;border-radius:5px;background:var(--imp-control-bg);color:var(--imp-text);font-size:12px;font-variant-numeric:tabular-nums;line-height:1.2;white-space:nowrap;pointer-events:none;opacity:0;visibility:hidden;transition:opacity var(--imp-transition),transform var(--imp-transition);z-index:5}.imp-action:hover .imp-count-tooltip:not([hidden]){opacity:1;visibility:visible;transform:translate(-50%) scale(1)}.imp-controls{display:flex;flex-direction:column;gap:4px}.imp-controls__row{display:flex;align-items:center;gap:4px;min-height:var(--imp-controls-height)}.imp-controls__group{display:flex;align-items:center;gap:2px;flex:0 0 auto}.imp-controls__row .imp-btn,.imp-controls__menu-anchor,.imp-action,.imp-volume,.imp-controls__time,.imp-controls__live{flex:0 0 auto}.imp-controls__spacer{flex:1;display:flex;align-items:center;justify-content:center;min-width:0}.imp-controls__chapter{font-size:12px;opacity:.85;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.imp-controls__time{font-variant-numeric:tabular-nums;font-size:13px;margin:0 6px;white-space:nowrap}.imp-controls__live{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;letter-spacing:.5px;margin:0 6px}.imp-controls__live:before{content:"";width:8px;height:8px;border-radius:50%;background:var(--imp-accent)}.imp-controls__menu-anchor{position:relative;display:flex}.imp-volume{display:flex;align-items:center}.imp-volume__slider{pointer-events:auto;appearance:none;-webkit-appearance:none;width:0;opacity:0;height:4px;border-radius:2px;background:linear-gradient(to right,var(--imp-text) var(--imp-volume-fill, 100%),var(--imp-track) var(--imp-volume-fill, 100%));cursor:pointer;transition:width var(--imp-transition),opacity var(--imp-transition)}.imp-volume:hover .imp-volume__slider,.imp-volume__slider:focus-visible{width:64px;opacity:1;margin-right:6px}.imp-volume__slider::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;background:var(--imp-text);border:0}.imp-volume__slider::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:var(--imp-text);border:0}.imp-progress{pointer-events:auto;position:relative;height:16px;display:flex;align-items:center;cursor:pointer;touch-action:none}.imp-progress--live{visibility:hidden}.imp-progress__heatmap{position:absolute;left:0;right:0;bottom:10px;height:36px;pointer-events:none;opacity:0;transition:opacity var(--imp-transition)}.imp-progress:hover .imp-progress__heatmap,.imp-progress--scrubbing .imp-progress__heatmap{opacity:1}.imp-progress__heatmap svg{width:100%;height:100%;display:block}.imp-progress__heatmap path{fill:#ffffff59}.imp-progress__buffered{position:absolute;left:0;height:4px;width:0;border-radius:2px;background:var(--imp-track-buffered);transition:height var(--imp-transition)}.imp-progress__track{position:relative;display:flex;gap:2px;width:100%;height:4px;transition:height var(--imp-transition)}.imp-progress:hover .imp-progress__track,.imp-progress--scrubbing .imp-progress__track,.imp-progress:hover .imp-progress__buffered,.imp-progress--scrubbing .imp-progress__buffered{height:6px}.imp-progress__segment{position:relative;flex-basis:0;height:100%;background:var(--imp-track);border-radius:2px;overflow:hidden}.imp-progress__fill{width:100%;height:100%;background:var(--imp-accent);transform:scaleX(0);transform-origin:left}.imp-progress__handle{position:absolute;width:12px;height:12px;border-radius:50%;background:var(--imp-accent);transform:translate(-50%) scale(0);transition:transform var(--imp-transition);pointer-events:none}.imp-progress:hover .imp-progress__handle,.imp-progress--scrubbing .imp-progress__handle{transform:translate(-50%) scale(1)}.imp-progress__tooltip{position:absolute;bottom:22px;transform:translate(-50%);display:flex;flex-direction:column;align-items:center;gap:4px;padding:4px;border-radius:6px;background:var(--imp-control-bg);opacity:0;visibility:hidden;transition:opacity var(--imp-transition);pointer-events:none;white-space:nowrap}.imp-progress__tooltip--visible{opacity:1;visibility:visible}.imp-progress__thumb{border-radius:4px;background-color:#111;background-repeat:no-repeat}.imp-progress__tooltip-chapter{font-size:12px;font-weight:600;max-width:220px;overflow:hidden;text-overflow:ellipsis}.imp-progress__tooltip-time{font-size:11px;font-variant-numeric:tabular-nums;opacity:.85}.imp-menu{pointer-events:auto;position:absolute;right:0;bottom:44px;min-width:160px;max-height:280px;overflow-y:auto;background:var(--imp-control-bg);border-radius:var(--imp-radius);padding:6px;backdrop-filter:blur(8px);z-index:5}.imp-menu__backdrop{display:none}.imp-menu__section+.imp-menu__section{margin-top:6px;border-top:1px solid rgba(255,255,255,.12);padding-top:6px}.imp-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;opacity:.6;padding:4px 8px}.imp-menu__item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;border:0;background:transparent;color:inherit;font:inherit;padding:7px 10px;border-radius:5px;cursor:pointer}.imp-menu__icon{display:inline-flex;width:18px;height:18px;flex-shrink:0}.imp-menu__icon svg,.imp-menu__icon img{width:100%;height:100%;object-fit:contain}.imp-menu__label{white-space:nowrap}.imp-menu__item:hover{background:#ffffff1f}.imp-menu__item--active{color:var(--imp-accent);font-weight:600}.imp-poster{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--imp-bg)}.imp-poster__image{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.imp-poster__play{position:relative;width:72px;height:72px;border-radius:50%;background:var(--imp-accent);padding:16px}.imp-poster__play:hover:not(:disabled){background:var(--imp-accent);transform:scale(1.08)}.imp-player--play-inverted .imp-poster__play,.imp-player--play-inverted .imp-center-btn--play{background:#ffffffd9;color:var(--imp-accent)}.imp-player--play-inverted .imp-poster__play:hover:not(:disabled),.imp-player--play-inverted .imp-center-btn--play:hover:not(:disabled){background:#fffffff2}.imp-error{pointer-events:auto;max-width:80%;padding:10px 16px;border-radius:8px;background:#000000bf;border:1px solid rgba(255,255,255,.2);font-size:13px;text-align:center}.imp-spinner{position:absolute;inset:0;margin:auto;width:48px;height:48px;border:4px solid rgba(255,255,255,.25);border-top-color:var(--imp-text);border-radius:50%;animation:imp-spin .8s linear infinite}@keyframes imp-spin{to{transform:rotate(360deg)}}.imp-pause-screen{grid-area:top;pointer-events:auto;padding:20px 24px;background:linear-gradient(rgba(0,0,0,.7),transparent);animation:imp-fade-in .22s ease}.imp-pause-screen--custom{grid-area:1 / 1 / -1 / -1;display:flex;align-items:center;justify-content:center;padding:16px;background:#0009;z-index:4}.imp-pause-screen__custom{pointer-events:auto;max-width:100%;max-height:100%;overflow:auto}.imp-pause-screen__default{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.imp-pause-screen__heading{flex:1;min-width:0}.imp-channel{display:flex;align-items:center;gap:10px;border:0;padding:0;background:transparent;color:inherit;font:inherit;text-align:left;flex-shrink:0}.imp-channel--link{cursor:pointer}.imp-channel--link:hover .imp-channel__name{text-decoration:underline}.imp-channel__avatar{width:44px;height:44px;border-radius:50%;background:linear-gradient(135deg,var(--imp-accent),#7b1fa2);background-size:cover;background-position:center}.imp-channel__avatar--rounded{border-radius:10px}.imp-channel__avatar--square{border-radius:0}.imp-channel__avatar--circle{border-radius:50%}.imp-channel__avatar{background-size:cover;background-position:center;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:700;flex-shrink:0}.imp-channel__name{font-size:14px;font-weight:600;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}.imp-pause-screen__title{font-size:20px;font-weight:700}.imp-pause-screen__description{margin-top:6px;font-size:14px;opacity:.85;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-sponsor{display:inline-flex;align-items:center;gap:7px;margin-top:10px;padding:5px 11px;border-radius:6px;max-width:100%;background:#00000073;border:1px solid rgba(255,255,255,.25);color:var(--imp-text);font-size:13px;font-weight:600;text-decoration:none;pointer-events:auto;transition:border-color var(--imp-transition),background var(--imp-transition)}.imp-sponsor:hover{border-color:var(--imp-accent);background:#0009}.imp-sponsor__label{flex-shrink:0;padding:1px 6px;border-radius:3px;background:var(--imp-accent);color:#fff;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px}.imp-sponsor__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes imp-fade-in{0%{opacity:0}}.imp-related{grid-area:middle;pointer-events:auto;align-self:stretch;display:flex;flex-direction:column;justify-content:center;gap:12px;padding:24px;background:#000c;animation:imp-fade-in .22s ease;z-index:2}.imp-related__close{align-self:flex-end}.imp-related__title{font-size:16px;font-weight:700}.imp-related__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;overflow-y:auto}.imp-related__card{display:flex;flex-direction:column;gap:6px;border:0;padding:0;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}.imp-related__thumb{position:relative;aspect-ratio:16 / 9;border-radius:6px;background-color:#222;background-size:cover;background-position:center;transition:transform var(--imp-transition)}.imp-related__card:hover .imp-related__thumb{transform:scale(1.04)}.imp-related__duration{position:absolute;right:6px;bottom:6px;padding:1px 5px;border-radius:4px;background:#000c;font-size:11px;font-variant-numeric:tabular-nums}.imp-related__card-title{font-size:13px;font-weight:600;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-playlist{position:absolute;display:flex;flex-direction:column;background:var(--imp-control-bg);backdrop-filter:blur(8px);z-index:6;--imp-thumb-w: 88}.imp-playlist--sidebar{top:0;right:0;bottom:0;width:min(320px,80%);animation:imp-slide-in .2s ease}.imp-playlist--bottom{left:0;right:0;bottom:0;max-height:46%;animation:imp-slide-up .2s ease;--imp-thumb-w: 128}.imp-playlist--bottom .imp-playlist__list{flex-direction:row;overflow-x:auto;overflow-y:hidden;padding:0 12px 12px}.imp-playlist--bottom .imp-playlist__item{flex-direction:column;align-items:stretch;flex:0 0 calc(var(--imp-thumb-w) * 1px + 12px)}.imp-playlist--bottom .imp-playlist__thumb{flex:0 0 auto;width:calc(var(--imp-thumb-w) * 1px)}@keyframes imp-slide-up{0%{transform:translateY(100%)}}.imp-playlist__tools{display:flex;align-items:center;gap:2px}.imp-playlist__heading{min-width:0}.imp-playlist__kicker{font-size:11px;font-weight:400;text-transform:uppercase;letter-spacing:.6px;opacity:.6}.imp-playlist__name{font-size:15px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes imp-slide-in{0%{transform:translate(100%)}}.imp-playlist__header{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;font-weight:700}.imp-playlist__list{overflow-y:auto;display:flex;flex-direction:column;padding:0 8px 8px;gap:4px}.imp-playlist__item{display:flex;gap:10px;align-items:center;padding:6px;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}.imp-playlist__item:hover{background:#ffffff1a}.imp-playlist__item--active{background:#ffffff24;box-shadow:inset 2px 0 0 var(--imp-accent)}.imp-playlist__thumb{flex:0 0 calc(var(--imp-thumb-w) * 1px);aspect-ratio:16 / 9;border-radius:4px;background-color:#222;background-size:cover;background-position:center;overflow:hidden}.imp-scenes__sprite{background-repeat:no-repeat;transform:scale(calc(var(--imp-thumb-w) / var(--imp-sprite-w, 160)));transform-origin:top left}.imp-playlist__title{font-size:13px;font-weight:600;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-playlist__duration{font-size:12px;opacity:.7;font-variant-numeric:tabular-nums}.imp-ad{position:absolute;inset:0;display:grid;grid-template-rows:auto 1fr auto;background:var(--imp-bg);z-index:10}.imp-ad__video{grid-row:1 / -1;grid-column:1;width:100%;height:100%;object-fit:contain;cursor:pointer}.imp-ad__spinner{grid-row:2;grid-column:1;justify-self:center;align-self:center;pointer-events:none}.imp-ad__hud{grid-row:1;grid-column:1;position:relative;z-index:2;display:flex;align-items:center;gap:10px;padding:12px 14px;pointer-events:none}.imp-ad__badge{padding:3px 8px;border-radius:4px;background:#000000b3;border:1px solid rgba(255,255,255,.4);font-size:12px;font-weight:700}.imp-ad__countdown{font-size:12px;font-variant-numeric:tabular-nums;text-shadow:0 1px 2px rgba(0,0,0,.8)}.imp-ad__actions{grid-row:3;grid-column:1;position:relative;z-index:2;display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:14px}.imp-ad__skip,.imp-ad__visit{border:1px solid rgba(255,255,255,.5);background:#000000bf;color:inherit;font:inherit;font-weight:600;padding:8px 14px;border-radius:6px;cursor:pointer;touch-action:manipulation}.imp-ad__skip:disabled{opacity:.7;cursor:default}.imp-ad__skip:hover:not(:disabled),.imp-ad__visit:hover{background:#fff3}.imp-ad--paused:after{content:"▶";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:48px;background:#0006;pointer-events:none}@media(max-width:767px){.imp-btn{width:28px;height:28px;padding:5px}.imp-controls__row{gap:0;min-height:38px}.imp-controls__group{gap:0}.imp-layer__bottom{padding:12px 6px 5px}.imp-controls__chapter{display:none}.imp-btn--seek-back,.imp-btn--seek-forward{width:26px;height:26px;padding:5px;opacity:.75}.imp-progress{height:12px}.imp-controls__time,.imp-controls__live{font-size:10px;margin:0 3px}.imp-poster__play{width:48px;height:48px;padding:11px}.imp-spinner{width:36px;height:36px;border-width:3px}.imp-pause-screen{padding:8px 10px}.imp-pause-screen__default{align-items:flex-start;gap:8px}.imp-pause-screen__title{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:0}.imp-pause-screen__description{display:none}.imp-channel{align-self:flex-start}.imp-channel__name{display:none}.imp-channel__avatar{width:32px;height:32px}.imp-sponsor{margin-top:6px;padding:4px 8px;font-size:11px;gap:5px}.imp-sponsor__label{font-size:9px}.imp-ad__hud{padding:8px 10px;gap:6px}.imp-ad__badge{font-size:10px;padding:2px 6px}.imp-ad__countdown{font-size:11px}.imp-ad__actions{padding:8px;gap:6px}.imp-ad__skip,.imp-ad__visit{padding:6px 10px;font-size:12px}.imp-ad--paused:after{font-size:36px}.imp-controls__menu-anchor{position:static}.imp-menu{position:absolute;inset:auto 0 0;box-sizing:border-box;min-width:0;max-width:none;max-height:80%;overflow-y:auto;border-radius:var(--imp-radius) var(--imp-radius) 0 0;padding:6px 8px calc(6px + env(safe-area-inset-bottom,0px));box-shadow:0 -8px 24px #00000080;animation:imp-slide-up .18s ease;z-index:6}.imp-menu__backdrop{display:block;position:absolute;inset:0;background:#00000080;pointer-events:auto;z-index:5;animation:imp-fade-in .18s ease}.imp-menu__item{padding:10px}.imp-playlist{inset:0;width:auto;max-height:none;border-radius:0;animation:imp-fade-in .18s ease}.imp-playlist--bottom .imp-playlist__list,.imp-playlist__list{flex-direction:column;overflow-x:hidden;overflow-y:auto}.imp-playlist--bottom .imp-playlist__item{flex-direction:row;align-items:center;flex:0 0 auto}.imp-playlist--bottom .imp-playlist__thumb,.imp-playlist__thumb{flex:0 0 120px;width:120px}}
1
+ .imp-player{--imp-accent: #e53935;--imp-bg: #000;--imp-text: #fff;--imp-control-bg: rgba(20, 20, 20, .85);--imp-track: rgba(255, 255, 255, .25);--imp-track-buffered: rgba(255, 255, 255, .35);--imp-radius: 8px;--imp-font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--imp-controls-height: 48px;--imp-transition: .18s ease;position:relative;width:100%;aspect-ratio:16 / 9;background:var(--imp-bg);color:var(--imp-text);font-family:var(--imp-font);font-size:14px;line-height:1.4;overflow:hidden;border-radius:var(--imp-radius);outline:none;user-select:none;-webkit-user-select:none;container-type:inline-size}.imp-player--fullscreen{border-radius:0}.imp-player [hidden],.imp-ad [hidden]{display:none!important}.imp-video{width:100%;height:100%;display:block;object-fit:contain}.imp-layer{position:absolute;inset:0;display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0,1fr);grid-template-areas:"top" "middle" "bottom";pointer-events:none}.imp-layer__middle{grid-area:middle;display:flex;align-items:center;justify-content:center}.imp-center-controls{position:absolute;inset:0;align-items:center;justify-content:center;gap:16px;pointer-events:none;transition:opacity var(--imp-transition)}.imp-player--idle .imp-center-controls{opacity:0;pointer-events:none}.imp-player--idle .imp-center-controls *,.imp-player--idle .imp-layer__bottom *{pointer-events:none}.imp-center-btn{pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;padding:10px;border:0;border-radius:50%;background:#00000073;color:#fff;cursor:pointer;transition:background var(--imp-transition),transform var(--imp-transition)}.imp-center-btn svg{width:100%;height:100%}.imp-center-btn--play{width:56px;height:56px;padding:14px;background:var(--imp-accent)}.imp-center-btn:hover:not(:disabled){background:#0009}.imp-center-btn--play:hover:not(:disabled){background:var(--imp-accent)}.imp-center-btn:active:not(:disabled){transform:scale(.9)}.imp-center-btn:disabled{opacity:.35;cursor:default}.imp-btn--seek-back,.imp-btn--seek-forward,.imp-center-btn--seek-back,.imp-center-btn--seek-forward{position:relative}.imp-seek-num{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:7px;font-weight:700;line-height:1;letter-spacing:-.5px;pointer-events:none;font-variant-numeric:tabular-nums}.imp-center-btn .imp-seek-num{font-size:11px}.imp-center-btn--seek-back,.imp-center-btn--seek-forward{background:transparent;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}.imp-center-btn--seek-back:hover:not(:disabled),.imp-center-btn--seek-forward:hover:not(:disabled){background:#0000004d}.imp-next-preview{position:absolute;z-index:8;width:220px;max-width:calc(100% - 16px);background:#14141cf5;border:1px solid rgba(255,255,255,.12);border-radius:10px;padding:8px;box-shadow:0 8px 24px #00000080;pointer-events:none;color:#fff;animation:imp-fade-in .12s ease}.imp-next-preview__kicker{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--imp-accent);margin-bottom:6px}.imp-next-preview__thumb{position:relative;width:100%;aspect-ratio:16 / 9;background:#000 center / cover no-repeat;border-radius:6px;overflow:hidden}.imp-next-preview__duration{position:absolute;right:4px;bottom:4px;padding:1px 5px;border-radius:3px;background:#000c;font-size:11px;font-variant-numeric:tabular-nums}.imp-next-preview__title{margin-top:6px;font-size:13px;font-weight:600;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-next-preview__meta{margin-top:3px;font-size:11px;opacity:.7}.imp-layer__bottom{grid-area:bottom;display:flex;flex-direction:column;background:linear-gradient(transparent,#000000b3);padding:24px 12px 8px;opacity:1;transition:opacity var(--imp-transition)}.imp-player--idle .imp-layer__bottom{opacity:0;pointer-events:none}.imp-player--idle{cursor:none}.imp-btn{pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;padding:6px;border:0;border-radius:6px;background:transparent;color:inherit;cursor:pointer;transition:background var(--imp-transition),transform var(--imp-transition)}.imp-btn svg{width:100%;height:100%}.imp-btn:hover:not(:disabled){background:#ffffff26}.imp-btn:focus-visible{outline:2px solid var(--imp-accent);outline-offset:1px}.imp-btn:disabled{opacity:.35;cursor:default}.imp-btn--active{color:var(--imp-accent)}.imp-btn--like.imp-btn--active{color:var(--imp-like, forestgreen)}.imp-btn--dislike.imp-btn--active{color:var(--imp-dislike, #e53935)}.imp-action{position:relative;display:inline-flex}.imp-count-tooltip{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%) scale(.9);padding:3px 7px;border-radius:5px;background:var(--imp-control-bg);color:var(--imp-text);font-size:12px;font-variant-numeric:tabular-nums;line-height:1.2;white-space:nowrap;pointer-events:none;opacity:0;visibility:hidden;transition:opacity var(--imp-transition),transform var(--imp-transition);z-index:5}.imp-action:hover .imp-count-tooltip:not([hidden]){opacity:1;visibility:visible;transform:translate(-50%) scale(1)}.imp-controls{display:flex;flex-direction:column;gap:4px}.imp-controls__row{display:flex;align-items:center;gap:4px;min-height:var(--imp-controls-height)}.imp-controls__group{display:flex;align-items:center;gap:2px;flex:0 0 auto}.imp-controls__row .imp-btn,.imp-controls__menu-anchor,.imp-action,.imp-volume,.imp-controls__time,.imp-controls__live{flex:0 0 auto}.imp-controls__spacer{flex:1;display:flex;align-items:center;justify-content:center;min-width:0}.imp-controls__chapter{font-size:12px;opacity:.85;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.imp-controls__time{font-variant-numeric:tabular-nums;font-size:13px;margin:0 6px;white-space:nowrap}.imp-controls__live{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;letter-spacing:.5px;margin:0 6px}.imp-controls__live:before{content:"";width:8px;height:8px;border-radius:50%;background:var(--imp-accent)}.imp-controls__menu-anchor{position:relative;display:flex}.imp-volume{display:flex;align-items:center}.imp-volume__slider{pointer-events:auto;appearance:none;-webkit-appearance:none;width:0;opacity:0;height:4px;border-radius:2px;background:linear-gradient(to right,var(--imp-text) var(--imp-volume-fill, 100%),var(--imp-track) var(--imp-volume-fill, 100%));cursor:pointer;transition:width var(--imp-transition),opacity var(--imp-transition)}.imp-volume:hover .imp-volume__slider,.imp-volume__slider:focus-visible{width:64px;opacity:1;margin-right:6px}.imp-volume__slider::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;background:var(--imp-text);border:0}.imp-volume__slider::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:var(--imp-text);border:0}.imp-progress{pointer-events:auto;position:relative;height:16px;display:flex;align-items:center;cursor:pointer;touch-action:none}.imp-progress--live{visibility:hidden}.imp-progress__heatmap{position:absolute;left:0;right:0;bottom:10px;height:36px;pointer-events:none;opacity:0;transition:opacity var(--imp-transition)}.imp-progress:hover .imp-progress__heatmap,.imp-progress--scrubbing .imp-progress__heatmap{opacity:1}.imp-progress__heatmap svg{width:100%;height:100%;display:block}.imp-progress__heatmap path{fill:#ffffff59}.imp-progress__buffered{position:absolute;left:0;height:4px;width:0;border-radius:2px;background:var(--imp-track-buffered);transition:height var(--imp-transition)}.imp-progress__track{position:relative;display:flex;gap:2px;width:100%;height:4px;transition:height var(--imp-transition)}.imp-progress:hover .imp-progress__track,.imp-progress--scrubbing .imp-progress__track,.imp-progress:hover .imp-progress__buffered,.imp-progress--scrubbing .imp-progress__buffered{height:6px}.imp-progress__segment{position:relative;flex-basis:0;height:100%;background:var(--imp-track);border-radius:2px;overflow:hidden}.imp-progress__fill{width:100%;height:100%;background:var(--imp-accent);transform:scaleX(0);transform-origin:left}.imp-progress__handle{position:absolute;width:12px;height:12px;border-radius:50%;background:var(--imp-accent);transform:translate(-50%) scale(0);transition:transform var(--imp-transition);pointer-events:none}.imp-progress:hover .imp-progress__handle,.imp-progress--scrubbing .imp-progress__handle{transform:translate(-50%) scale(1)}.imp-progress__tooltip{position:absolute;bottom:22px;transform:translate(-50%);display:flex;flex-direction:column;align-items:center;gap:4px;padding:4px;border-radius:6px;background:var(--imp-control-bg);opacity:0;visibility:hidden;transition:opacity var(--imp-transition);pointer-events:none;white-space:nowrap}.imp-progress__tooltip--visible{opacity:1;visibility:visible}.imp-progress__thumb{border-radius:4px;background-color:#111;background-repeat:no-repeat}.imp-progress__tooltip-chapter{font-size:12px;font-weight:600;max-width:220px;overflow:hidden;text-overflow:ellipsis}.imp-progress__tooltip-time{font-size:11px;font-variant-numeric:tabular-nums;opacity:.85}.imp-menu{pointer-events:auto;position:absolute;right:0;bottom:44px;min-width:160px;max-height:280px;overflow-y:auto;background:var(--imp-control-bg);border-radius:var(--imp-radius);padding:6px;backdrop-filter:blur(8px);z-index:5}.imp-menu__backdrop{display:none}.imp-menu--wide{min-width:240px}.imp-menu__section+.imp-menu__section{margin-top:6px;border-top:1px solid rgba(255,255,255,.12);padding-top:6px}.imp-menu__title{font-size:11px;text-transform:uppercase;letter-spacing:.6px;opacity:.6;padding:4px 8px}.imp-menu__item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;border:0;background:transparent;color:inherit;font:inherit;padding:7px 10px;border-radius:5px;cursor:pointer}.imp-menu__icon{display:inline-flex;width:18px;height:18px;flex-shrink:0}.imp-menu__icon svg,.imp-menu__icon img{width:100%;height:100%;object-fit:contain}.imp-menu__label{white-space:nowrap}.imp-menu__item:hover{background:#ffffff1f}.imp-menu__item--active{color:var(--imp-accent);font-weight:600}.imp-menu__row .imp-menu__value{margin-left:auto;opacity:.7;white-space:nowrap}.imp-menu__chevron{display:inline-flex;width:16px;height:16px;flex-shrink:0;opacity:.7}.imp-menu__row .imp-menu__chevron{margin-left:4px}.imp-menu__chevron svg{width:100%;height:100%}.imp-menu__back{font-weight:600;border-bottom:1px solid rgba(255,255,255,.12);border-radius:5px 5px 0 0;margin-bottom:4px}.imp-menu__back .imp-menu__chevron{width:18px;height:18px;opacity:.9}.imp-poster{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--imp-bg)}.imp-poster__image{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.imp-poster__play{position:relative;width:72px;height:72px;border-radius:50%;background:var(--imp-accent);padding:16px}.imp-poster__play:hover:not(:disabled){background:var(--imp-accent);transform:scale(1.08)}.imp-player--play-inverted .imp-poster__play,.imp-player--play-inverted .imp-center-btn--play{background:#ffffffd9;color:var(--imp-accent)}.imp-player--play-inverted .imp-poster__play:hover:not(:disabled),.imp-player--play-inverted .imp-center-btn--play:hover:not(:disabled){background:#fffffff2}.imp-error{pointer-events:auto;max-width:80%;padding:10px 16px;border-radius:8px;background:#000000bf;border:1px solid rgba(255,255,255,.2);font-size:13px;text-align:center}.imp-spinner{position:absolute;inset:0;margin:auto;width:48px;height:48px;border:4px solid rgba(255,255,255,.25);border-top-color:var(--imp-text);border-radius:50%;animation:imp-spin .8s linear infinite}@keyframes imp-spin{to{transform:rotate(360deg)}}.imp-pause-screen{grid-area:top;pointer-events:auto;padding:20px 24px;background:linear-gradient(rgba(0,0,0,.7),transparent);animation:imp-fade-in .22s ease}.imp-pause-screen--custom{grid-area:1 / 1 / -1 / -1;display:flex;align-items:center;justify-content:center;padding:16px;background:#0009;z-index:4}.imp-pause-screen__custom{pointer-events:auto;max-width:100%;max-height:100%;overflow:auto}.imp-pause-screen__default{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.imp-pause-screen__heading{flex:1;min-width:0}.imp-channel{display:flex;align-items:center;gap:10px;border:0;padding:0;background:transparent;color:inherit;font:inherit;text-align:left;flex-shrink:0}.imp-channel--link{cursor:pointer}.imp-channel--link:hover .imp-channel__name{text-decoration:underline}.imp-channel__avatar{width:44px;height:44px;border-radius:50%;background:linear-gradient(135deg,var(--imp-accent),#7b1fa2);background-size:cover;background-position:center}.imp-channel__avatar--rounded{border-radius:10px}.imp-channel__avatar--square{border-radius:0}.imp-channel__avatar--circle{border-radius:50%}.imp-channel__avatar{background-size:cover;background-position:center;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:700;flex-shrink:0}.imp-channel__name{font-size:14px;font-weight:600;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}.imp-pause-screen__title{font-size:20px;font-weight:700}.imp-pause-screen__description{margin-top:6px;font-size:14px;opacity:.85;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-sponsor{display:inline-flex;align-items:center;gap:7px;margin:0 0 10px -8px;padding:5px 11px 5px 8px;border-radius:6px;max-width:100%;background:#00000073;border:1px solid rgba(255,255,255,.25);color:var(--imp-text);font-size:13px;font-weight:600;text-decoration:none;pointer-events:auto;transition:border-color var(--imp-transition),background var(--imp-transition)}.imp-sponsor:hover{border-color:var(--imp-accent);background:#0009}.imp-sponsor__label{flex-shrink:0;padding:1px 6px;border-radius:3px;background:var(--imp-accent);color:#fff;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px}.imp-sponsor__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes imp-fade-in{0%{opacity:0}}.imp-related{grid-area:middle;pointer-events:auto;align-self:stretch;display:flex;flex-direction:column;justify-content:center;gap:12px;padding:24px;background:#000c;animation:imp-fade-in .22s ease;z-index:2}.imp-related__close{align-self:flex-end}.imp-related__title{font-size:16px;font-weight:700}.imp-related__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;overflow-y:auto}.imp-related__card{display:flex;flex-direction:column;gap:6px;border:0;padding:0;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}.imp-related__thumb{position:relative;aspect-ratio:16 / 9;border-radius:6px;background-color:#222;background-size:cover;background-position:center;transition:transform var(--imp-transition)}.imp-related__card:hover .imp-related__thumb{transform:scale(1.04)}.imp-related__duration{position:absolute;right:6px;bottom:6px;padding:1px 5px;border-radius:4px;background:#000c;font-size:11px;font-variant-numeric:tabular-nums}.imp-related__card-title{font-size:13px;font-weight:600;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-playlist{position:absolute;display:flex;flex-direction:column;background:var(--imp-control-bg);backdrop-filter:blur(8px);z-index:6;--imp-thumb-w: 88}.imp-playlist--sidebar{top:0;right:0;bottom:0;width:min(320px,80%);animation:imp-slide-in .2s ease}.imp-playlist--bottom{left:0;right:0;bottom:0;max-height:46%;animation:imp-slide-up .2s ease;--imp-thumb-w: 128}.imp-playlist--bottom .imp-playlist__list{flex-direction:row;overflow-x:auto;overflow-y:hidden;padding:0 12px 12px}.imp-playlist--bottom .imp-playlist__item{flex-direction:column;align-items:stretch;flex:0 0 calc(var(--imp-thumb-w) * 1px + 12px)}.imp-playlist--bottom .imp-playlist__thumb{flex:0 0 auto;width:calc(var(--imp-thumb-w) * 1px)}@keyframes imp-slide-up{0%{transform:translateY(100%)}}.imp-playlist__tools{display:flex;align-items:center;gap:2px}.imp-playlist__heading{min-width:0}.imp-playlist__kicker{font-size:11px;font-weight:400;text-transform:uppercase;letter-spacing:.6px;opacity:.6}.imp-playlist__name{font-size:15px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes imp-slide-in{0%{transform:translate(100%)}}.imp-playlist__header{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;font-weight:700}.imp-playlist__list{overflow-y:auto;display:flex;flex-direction:column;padding:0 8px 8px;gap:4px}.imp-playlist__item{display:flex;gap:10px;align-items:center;padding:6px;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}.imp-playlist__item:hover{background:#ffffff1a}.imp-playlist__item--active{background:#ffffff24;box-shadow:inset 2px 0 0 var(--imp-accent)}.imp-playlist__thumb{flex:0 0 calc(var(--imp-thumb-w) * 1px);aspect-ratio:16 / 9;border-radius:4px;background-color:#222;background-size:cover;background-position:center;overflow:hidden}.imp-scenes__sprite{background-repeat:no-repeat;transform:scale(calc(var(--imp-thumb-w) / var(--imp-sprite-w, 160)));transform-origin:top left}.imp-playlist__title{font-size:13px;font-weight:600;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.imp-playlist__duration{font-size:12px;opacity:.7;font-variant-numeric:tabular-nums}.imp-ad{position:absolute;inset:0;display:grid;grid-template-rows:auto 1fr auto;background:var(--imp-bg);z-index:10}.imp-ad__video{grid-row:1 / -1;grid-column:1;width:100%;height:100%;object-fit:contain;cursor:pointer}.imp-ad__spinner{grid-row:2;grid-column:1;justify-self:center;align-self:center;pointer-events:none}.imp-ad__hud{grid-row:1;grid-column:1;position:relative;z-index:2;display:flex;align-items:center;gap:10px;padding:12px 14px;pointer-events:none}.imp-ad__badge{padding:3px 8px;border-radius:4px;background:#000000b3;border:1px solid rgba(255,255,255,.4);font-size:12px;font-weight:700}.imp-ad__countdown{font-size:12px;font-variant-numeric:tabular-nums;text-shadow:0 1px 2px rgba(0,0,0,.8)}.imp-ad__actions{grid-row:3;grid-column:1;position:relative;z-index:2;display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:14px}.imp-ad__skip,.imp-ad__visit{border:1px solid rgba(255,255,255,.5);background:#000000bf;color:inherit;font:inherit;font-weight:600;padding:8px 14px;border-radius:6px;cursor:pointer;touch-action:manipulation}.imp-ad__skip:disabled{opacity:.7;cursor:default}.imp-ad__skip:hover:not(:disabled),.imp-ad__visit:hover{background:#fff3}.imp-ad--paused:after{content:"▶";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:48px;background:#0006;pointer-events:none}@media(max-width:767px){.imp-btn{width:28px;height:28px;padding:5px}.imp-controls__row{gap:0;min-height:38px}.imp-controls__group{gap:0}.imp-layer__bottom{padding:12px 6px 5px}.imp-controls__chapter{display:none}.imp-btn--seek-back,.imp-btn--seek-forward{width:26px;height:26px;padding:5px;opacity:.75}.imp-progress{height:12px}.imp-controls__time,.imp-controls__live{font-size:10px;margin:0 3px}.imp-poster__play{width:48px;height:48px;padding:11px}.imp-spinner{width:36px;height:36px;border-width:3px}.imp-pause-screen{padding:8px 10px}.imp-pause-screen__default{align-items:flex-start;gap:8px}.imp-pause-screen__title{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:0}.imp-pause-screen__description{display:none}.imp-channel{align-self:flex-start}.imp-channel__name{display:none}.imp-channel__avatar{width:32px;height:32px}.imp-sponsor{margin-top:6px;padding:4px 8px;font-size:11px;gap:5px}.imp-sponsor__label{font-size:9px}.imp-ad__hud{padding:8px 10px;gap:6px}.imp-ad__badge{font-size:10px;padding:2px 6px}.imp-ad__countdown{font-size:11px}.imp-ad__actions{padding:8px;gap:6px}.imp-ad__skip,.imp-ad__visit{padding:6px 10px;font-size:12px}.imp-ad--paused:after{font-size:36px}.imp-controls__menu-anchor{position:static}.imp-menu{position:absolute;inset:auto 0 0;box-sizing:border-box;min-width:0;max-width:none;max-height:80%;overflow-y:auto;border-radius:var(--imp-radius) var(--imp-radius) 0 0;padding:6px 8px calc(6px + env(safe-area-inset-bottom,0px));box-shadow:0 -8px 24px #00000080;animation:imp-slide-up .18s ease;z-index:6}.imp-menu__backdrop{display:block;position:absolute;inset:0;background:#00000080;pointer-events:auto;z-index:5;animation:imp-fade-in .18s ease}.imp-menu__item{padding:10px}.imp-playlist{inset:0;width:auto;max-height:none;border-radius:0;animation:imp-fade-in .18s ease}.imp-playlist--bottom .imp-playlist__list,.imp-playlist__list{flex-direction:column;overflow-x:hidden;overflow-y:auto}.imp-playlist--bottom .imp-playlist__item{flex-direction:row;align-items:center;flex:0 0 auto}.imp-playlist--bottom .imp-playlist__thumb,.imp-playlist__thumb{flex:0 0 120px;width:120px}}
package/dist/types.d.ts CHANGED
@@ -103,6 +103,11 @@ export interface VideoSource {
103
103
  * "most replayed"). Sparse — only the moments you have data for.
104
104
  */
105
105
  heatmap?: HeatmapPoint[];
106
+ /**
107
+ * Short info lines shown in the "next video" hover preview (and reusable in
108
+ * other previews), e.g. `["2.3K views", "User uploaded"]`. Free text.
109
+ */
110
+ previewMeta?: string[];
106
111
  /** Free-form user data, carried around untouched. */
107
112
  meta?: Record<string, unknown>;
108
113
  }
@@ -164,12 +169,18 @@ export interface AdsOptions {
164
169
  */
165
170
  playOn?: 'every' | 'first';
166
171
  }
167
- /** A consumer-defined entry in the actions dropdown. */
172
+ /** A consumer-defined entry in the actions UI. */
168
173
  export interface CustomAction {
169
174
  id: string;
170
175
  title: string;
171
- /** Icon: image URL or raw `<svg>` markup. Optional. */
176
+ /** Icon: image URL or raw `<svg>` markup. Required when `placement: "bar"`. */
172
177
  icon?: string;
178
+ /**
179
+ * Where the action lives:
180
+ * - `"menu"` (default): an item in the ⋯ dropdown;
181
+ * - `"bar"`: a dedicated icon button in the control bar (tooltip = `title`).
182
+ */
183
+ placement?: 'menu' | 'bar';
173
184
  }
174
185
  export type BuiltinActionId = 'like' | 'dislike' | 'addTo' | 'share' | 'report';
175
186
  /**
@@ -196,6 +207,24 @@ export interface ActionsOptions {
196
207
  /** Extra dropdown entries. Click emits `customaction` with the entry id. */
197
208
  custom?: CustomAction[];
198
209
  }
210
+ /**
211
+ * Where a settings-type control lives:
212
+ * - `"gear"` (default): a section inside the unified ⚙ settings dropdown;
213
+ * - `"bar"`: its own dedicated button in the control bar;
214
+ * - `false`: off. `true` is an alias for `"gear"`.
215
+ */
216
+ export type SettingPlacement = boolean | 'gear' | 'bar';
217
+ /** What the "next video" hover preview shows. `true`/`false` toggle all of it. */
218
+ export interface NextPreviewOptions {
219
+ /** Thumbnail (next source's `poster`). Default true. */
220
+ thumbnail?: boolean;
221
+ /** Title (next source's `title`). Default true. */
222
+ title?: boolean;
223
+ /** Duration badge (next source's `duration`). Default true. */
224
+ duration?: boolean;
225
+ /** Extra info lines from the next source's `previewMeta`. Default true. */
226
+ meta?: boolean;
227
+ }
199
228
  export interface ControlsOptions {
200
229
  play?: boolean;
201
230
  progress?: boolean;
@@ -203,22 +232,43 @@ export interface ControlsOptions {
203
232
  volume?: boolean;
204
233
  fullscreen?: boolean;
205
234
  pip?: boolean;
206
- /** Playback-speed menu (speedometer icon). */
207
- settings?: boolean;
208
- /** Quality menu (gear icon). OFF by default; needs `source.qualities` or an HLS source. */
209
- quality?: boolean;
235
+ /** Playback speed. Default `"gear"` (inside the settings dropdown). */
236
+ speed?: SettingPlacement;
237
+ /** @deprecated alias for `speed`. */
238
+ settings?: SettingPlacement;
239
+ /** Quality. Default `"gear"`; needs `source.qualities` or an HLS source to appear. */
240
+ quality?: SettingPlacement;
210
241
  /** Scene list button — appears when the source has chapters. Default true. */
211
242
  scenes?: boolean;
212
243
  /** Popularity heatmap above the progress bar (needs `source.heatmap` data). Default true. */
213
244
  heatmap?: boolean;
214
- subtitles?: boolean;
245
+ /** Subtitles. Default `"gear"` (inside the settings dropdown). */
246
+ subtitles?: SettingPlacement;
215
247
  /** Skip-back / skip-forward buttons. Pass an object to change the step (seconds). */
216
248
  seekButtons?: boolean | {
217
249
  back?: number;
218
250
  forward?: number;
219
251
  };
252
+ /**
253
+ * Where the prev/seek/play/next cluster lives:
254
+ * - `"overlay"` (default): big buttons centered over the video, on every viewport;
255
+ * - `"bar"`: seek buttons in the bottom control bar (the cluster still appears
256
+ * over the video on mobile). This is the pre-0.3 desktop behaviour.
257
+ */
258
+ seekPlacement?: 'overlay' | 'bar';
220
259
  /** Previous / next / list buttons (only rendered when a playlist is present). */
221
260
  playlist?: boolean;
261
+ /**
262
+ * Hide the "previous" button in the control bar (the bar keeps only "next").
263
+ * Default true. The mobile center cluster still shows prev. Set false to bring
264
+ * the bar prev button back.
265
+ */
266
+ hidePrev?: boolean;
267
+ /**
268
+ * Hover preview of the next playlist item over the "next" button (desktop).
269
+ * Default true when a playlist is present. Pass an object to pick fields.
270
+ */
271
+ nextPreview?: boolean | NextPreviewOptions;
222
272
  /** ms of pointer inactivity before controls fade out during playback. Default 2500. */
223
273
  hideDelay?: number;
224
274
  }
@@ -235,6 +285,15 @@ export interface PlaylistOptions {
235
285
  /** Panel placement: `"sidebar"` (right, default) or `"bottom"` (horizontal strip). */
236
286
  layout?: 'sidebar' | 'bottom';
237
287
  }
288
+ /** Which parts of the default pause-screen overlay to render (all default true). */
289
+ export interface PauseScreenContent {
290
+ /** Video title. */
291
+ title?: boolean;
292
+ /** Video description. */
293
+ description?: boolean;
294
+ /** Sponsor / promo link. */
295
+ sponsor?: boolean;
296
+ }
238
297
  /** Scene (chapter) list panel — timecodes with sprite previews. */
239
298
  export interface ScenesOptions {
240
299
  /** Panel placement. Default `"bottom"`. */
@@ -297,10 +356,13 @@ export interface PlayerOptions {
297
356
  keyboard?: boolean;
298
357
  controls?: ControlsOptions;
299
358
  /**
300
- * Pause-screen "slot". `true` renders the default title/description overlay,
301
- * an element or a factory lets you inject arbitrary markup.
359
+ * Pause-screen "slot":
360
+ * - `true` (default) / `false` show or hide the default title/description overlay;
361
+ * - an `HTMLElement` or factory — inject arbitrary markup;
362
+ * - a `PauseScreenContent` object — default overlay with specific parts hidden
363
+ * (e.g. `{ title: false, description: false }` when the page renders them itself).
302
364
  */
303
- pauseScreen?: boolean | HTMLElement | ((player: unknown) => HTMLElement);
365
+ pauseScreen?: boolean | HTMLElement | ((player: unknown) => HTMLElement) | PauseScreenContent;
304
366
  related?: RelatedOptions;
305
367
  /** Ad configuration: pre/mid/post rolls, skip timer, playlist frequency. */
306
368
  adConfig?: AdsOptions;
@@ -26,6 +26,14 @@ export declare class Controls {
26
26
  private moreWrap;
27
27
  private qualityBtn;
28
28
  private qualityMenu;
29
+ /** Unified ⚙ dropdown holding the settings placed in `"gear"`. */
30
+ private gearBtn;
31
+ private gearMenu;
32
+ /** Which settings live in the gear menu (vs their own bar button / off). */
33
+ private gear;
34
+ /** Next-up hover preview (desktop). */
35
+ private nextPreviewEl;
36
+ private nextPreviewOpts;
29
37
  private scenesBtn;
30
38
  private likeBtn;
31
39
  private dislikeBtn;
@@ -40,8 +48,6 @@ export declare class Controls {
40
48
  private centerPlayBtn;
41
49
  private centerPrevBtn;
42
50
  private centerNextBtn;
43
- /** Controls that live in the center cluster on mobile (not in the bottom bar). */
44
- private static readonly CENTER_KEYS;
45
51
  private collapsibles;
46
52
  private overflowed;
47
53
  private resizeObserver;
@@ -55,6 +61,17 @@ export declare class Controls {
55
61
  private registerCollapsible;
56
62
  /** Center-cluster button — deliberately NOT `.imp-btn` (own sizing/look). */
57
63
  private makeCenterButton;
64
+ /** Overlay the seek step value (e.g. "15") inside the circular-arrow icon. */
65
+ private addStepBadge;
66
+ /** Sections for the gear when overflowed into ⋯ (expanded, no drill-down). */
67
+ private gearSections;
68
+ /** Gear drill-down rows: one per setting, each showing its current value. */
69
+ private gearEntries;
70
+ private toggleGearMenu;
71
+ private setupNextPreview;
72
+ private bindNextPreview;
73
+ private showNextPreview;
74
+ private hideNextPreview;
58
75
  /** like/dislike — visible buttons (collapsible), highlightable via `setLikeState`. */
59
76
  private buildLikeDislike;
60
77
  private attachCountTooltip;
package/dist/ui/menu.d.ts CHANGED
@@ -10,6 +10,15 @@ export interface MenuSection {
10
10
  items: MenuItem[];
11
11
  onSelect(value: string): void;
12
12
  }
13
+ /** One row in the settings (gear) drill-down: label + current value → options. */
14
+ export interface SettingEntry {
15
+ key: string;
16
+ label: string;
17
+ /** Current value shown on the row, e.g. "Auto", "1×", "Off". */
18
+ value: string;
19
+ /** The options panel to drill into when the row is clicked. */
20
+ section(): MenuSection;
21
+ }
13
22
  /**
14
23
  * Popup menu anchored above a control button. One instance per button;
15
24
  * rebuilt from data on every open, closed on outside click / Escape.
@@ -24,6 +33,15 @@ export declare class Menu {
24
33
  get open(): boolean;
25
34
  toggle(sections: MenuSection[]): void;
26
35
  show(sections: MenuSection[]): void;
36
+ /** Settings (gear) drill-down: a root list of rows, each opening its options. */
37
+ toggleSettings(title: string, entries: SettingEntry[]): void;
38
+ showSettings(_title: string, entries: SettingEntry[]): void;
39
+ private renderSettingsRoot;
40
+ private renderSettingsDetail;
41
+ /** Build one option block (radio items) from a section. */
42
+ private renderSection;
43
+ /** Reveal the populated menu + backdrop and arm the outside-click listener. */
44
+ private reveal;
27
45
  close(): void;
28
46
  destroy(): void;
29
47
  }
@@ -29,10 +29,18 @@ export declare class PauseScreen {
29
29
  private sponsorLabel;
30
30
  private sponsorText;
31
31
  private custom;
32
+ /** Which parts the consumer allows (a hidden part stays hidden even with data). */
33
+ private visible;
32
34
  constructor(labels: PlayerLabels);
33
35
  setCustomContent(element: HTMLElement | null): void;
34
36
  /** True while consumer-provided custom content is mounted. */
35
37
  get hasCustom(): boolean;
38
+ /** Hide specific parts of the default overlay (consumer renders them itself). */
39
+ setVisibility(parts: {
40
+ title?: boolean;
41
+ description?: boolean;
42
+ sponsor?: boolean;
43
+ }): void;
36
44
  setSource(source: VideoSource | null): void;
37
45
  show(): void;
38
46
  hide(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itube-modern-player",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Lightweight, framework-agnostic HTML5 video player: HLS streams, playlists, chapters, VTT subtitles, sprite previews, VAST ads. Ships with a Vue 3 wrapper.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",