diff --git a/packages/html/src/define/ui/slider-thumbnail.ts b/packages/html/src/define/ui/slider-thumbnail.ts
new file mode 100644
index 00000000..ee32c72f
--- /dev/null
+++ b/packages/html/src/define/ui/slider-thumbnail.ts
@@ -0,0 +1,10 @@
+import { SliderThumbnailElement } from '../../ui/slider/slider-thumbnail-element';
+import { safeDefine } from '../safe-define';
+
+safeDefine(SliderThumbnailElement);
+
+declare global {
+ interface HTMLElementTagNameMap {
+ [SliderThumbnailElement.tagName]: SliderThumbnailElement;
+ }
+}
diff --git a/packages/html/src/define/ui/time-slider.ts b/packages/html/src/define/ui/time-slider.ts
index 25186875..fda8f5ac 100644
--- a/packages/html/src/define/ui/time-slider.ts
+++ b/packages/html/src/define/ui/time-slider.ts
@@ -1,6 +1,7 @@
import { SliderBufferElement } from '../../ui/slider/slider-buffer-element';
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
+import { SliderThumbnailElement } from '../../ui/slider/slider-thumbnail-element';
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
import { SliderValueElement } from '../../ui/slider/slider-value-element';
import { TimeSliderElement } from '../../ui/time-slider/time-slider-element';
@@ -11,6 +12,7 @@ safeDefine(TimeSliderElement);
safeDefine(SliderBufferElement);
safeDefine(SliderFillElement);
safeDefine(SliderThumbElement);
+safeDefine(SliderThumbnailElement);
safeDefine(SliderTrackElement);
safeDefine(SliderValueElement);
diff --git a/packages/html/src/index.ts b/packages/html/src/index.ts
index 35da8c60..7e1e3dc5 100644
--- a/packages/html/src/index.ts
+++ b/packages/html/src/index.ts
@@ -35,6 +35,7 @@ export { SliderElement } from './ui/slider/slider-element';
export type { SliderEventMap, SliderValueEventDetail } from './ui/slider/slider-events';
export { SliderFillElement } from './ui/slider/slider-fill-element';
export { SliderThumbElement } from './ui/slider/slider-thumb-element';
+export { SliderThumbnailElement } from './ui/slider/slider-thumbnail-element';
export { SliderTrackElement } from './ui/slider/slider-track-element';
export { SliderValueElement } from './ui/slider/slider-value-element';
export { ThumbnailElement } from './ui/thumbnail/thumbnail-element';
diff --git a/packages/html/src/ui/slider/slider-thumbnail-element.ts b/packages/html/src/ui/slider/slider-thumbnail-element.ts
new file mode 100644
index 00000000..75f0cf1c
--- /dev/null
+++ b/packages/html/src/ui/slider/slider-thumbnail-element.ts
@@ -0,0 +1,21 @@
+import type { PropertyValues } from '@videojs/element';
+import { ContextConsumer } from '@videojs/element/context';
+
+import { ThumbnailElement } from '../thumbnail/thumbnail-element';
+import { sliderContext } from './context';
+
+// @ts-expect-error TS2417 — tagName narrows to a different literal for custom element registration.
+export class SliderThumbnailElement extends ThumbnailElement {
+ static override readonly tagName = 'media-slider-thumbnail';
+
+ readonly #ctx = new ContextConsumer(this, {
+ context: sliderContext,
+ subscribe: true,
+ });
+
+ protected override update(changed: PropertyValues): void {
+ const ctx = this.#ctx.value;
+ if (ctx) this.time = ctx.pointerValue;
+ super.update(changed);
+ }
+}
diff --git a/packages/html/src/ui/slider/tests/slider-thumbnail-element.test.ts b/packages/html/src/ui/slider/tests/slider-thumbnail-element.test.ts
new file mode 100644
index 00000000..cccf96ef
--- /dev/null
+++ b/packages/html/src/ui/slider/tests/slider-thumbnail-element.test.ts
@@ -0,0 +1,94 @@
+import { afterEach, describe, expect, it } from 'vitest';
+
+import { ThumbnailElement } from '../../thumbnail/thumbnail-element';
+import { SliderElement } from '../slider-element';
+import { SliderThumbnailElement } from '../slider-thumbnail-element';
+
+let tagCounter = 0;
+
+function uniqueTag(base: string): string {
+ return `${base}-${tagCounter++}`;
+}
+
+function createElement(Base: abstract new () => Element): Element {
+ const tag = uniqueTag('test-slt');
+ customElements.define(tag, class extends (Base as unknown as typeof HTMLElement) {});
+ return document.createElement(tag) as Element;
+}
+
+afterEach(() => {
+ document.body.innerHTML = '';
+});
+
+describe('SliderThumbnailElement', () => {
+ it('has the correct tag name', () => {
+ expect(SliderThumbnailElement.tagName).toBe('media-slider-thumbnail');
+ });
+
+ it('extends ThumbnailElement', () => {
+ const el = createElement(SliderThumbnailElement);
+ expect(el).toBeInstanceOf(ThumbnailElement);
+ });
+
+ it('has a shadow root with an img element', () => {
+ const el = createElement(SliderThumbnailElement);
+ expect(el.shadowRoot).toBeTruthy();
+
+ const img = el.shadowRoot!.querySelector('img');
+ expect(img).toBeTruthy();
+ expect(img!.getAttribute('aria-hidden')).toBe('true');
+ });
+
+ it('inherits time property from ThumbnailElement', () => {
+ const el = createElement(SliderThumbnailElement);
+ expect(el.time).toBe(0);
+
+ el.time = 10;
+ expect(el.time).toBe(10);
+ });
+
+ it('sets data-hidden when no thumbnails are available', async () => {
+ const el = createElement(SliderThumbnailElement);
+
+ document.body.appendChild(el);
+ await el.updateComplete;
+
+ expect(el.hasAttribute('data-hidden')).toBe(true);
+ });
+
+ it('reads pointerValue from slider context as time', async () => {
+ const slider = createElement(SliderElement);
+ const thumbnail = createElement(SliderThumbnailElement);
+
+ thumbnail.thumbnails = [
+ { url: 'thumb-0.jpg', startTime: 0 },
+ { url: 'thumb-30.jpg', startTime: 30 },
+ { url: 'thumb-60.jpg', startTime: 60 },
+ ];
+
+ slider.appendChild(thumbnail);
+ document.body.appendChild(slider);
+
+ await slider.updateComplete;
+ await thumbnail.updateComplete;
+
+ // In idle state, pointerPercent=0 → pointerValue=0 → selects 'thumb-0.jpg'.
+ const img = thumbnail.shadowRoot!.querySelector('img');
+ expect(img!.getAttribute('src')).toBe('thumb-0.jpg');
+ });
+
+ it('does not have data-hidden when thumbnails match', async () => {
+ const slider = createElement(SliderElement);
+ const thumbnail = createElement(SliderThumbnailElement);
+
+ thumbnail.thumbnails = [{ url: 'thumb.jpg', startTime: 0 }];
+
+ slider.appendChild(thumbnail);
+ document.body.appendChild(slider);
+
+ await slider.updateComplete;
+ await thumbnail.updateComplete;
+
+ expect(thumbnail.hasAttribute('data-hidden')).toBe(false);
+ });
+});