mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(html): add slider thumbnail element (#714)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<Element extends HTMLElement>(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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user