mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(core): add play button component (#383)
This commit is contained in:
@@ -1 +1,9 @@
|
||||
// TODO: Implement PlayButtonElement then register it here
|
||||
import { PlayButtonElement } from '../../ui/play-button/play-button-element';
|
||||
|
||||
customElements.define(PlayButtonElement.tagName, PlayButtonElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[PlayButtonElement.tagName]: PlayButtonElement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,3 +16,6 @@ export * from './store/types';
|
||||
|
||||
// Primitives
|
||||
export * from './ui/media-element';
|
||||
|
||||
// UI Components
|
||||
export { PlayButtonElement } from './ui/play-button/play-button-element';
|
||||
|
||||
@@ -36,7 +36,7 @@ export class PlayerController<Store extends PlayerStore, Result = Store> impleme
|
||||
readonly #selector: Selector<InferStoreState<Store>, Result> | undefined;
|
||||
|
||||
#consumer: ContextConsumer<PlayerContext<Store>, PlayerControllerHost>;
|
||||
#storeCtrl: StoreController<Store, Result> | null = null;
|
||||
#store: StoreController<Store, Result> | null = null;
|
||||
|
||||
constructor(host: PlayerControllerHost, context: PlayerContext<Store>);
|
||||
constructor(
|
||||
@@ -61,15 +61,15 @@ export class PlayerController<Store extends PlayerStore, Result = Store> impleme
|
||||
host.addController(this);
|
||||
}
|
||||
|
||||
get value(): Result {
|
||||
get value(): Result | undefined {
|
||||
const ctx = this.#consumer.value;
|
||||
if (!ctx) throw new Error('Player context not available');
|
||||
if (!ctx) return undefined;
|
||||
|
||||
// Without selector: return store directly
|
||||
if (!this.#selector) return ctx.store as unknown as Result;
|
||||
|
||||
// With selector: use StoreController
|
||||
return this.#storeCtrl!.value;
|
||||
return this.#store?.value;
|
||||
}
|
||||
|
||||
hostConnected(): void {
|
||||
@@ -78,15 +78,15 @@ export class PlayerController<Store extends PlayerStore, Result = Store> impleme
|
||||
}
|
||||
|
||||
hostDisconnected(): void {
|
||||
this.#storeCtrl = null;
|
||||
this.#store = null;
|
||||
}
|
||||
|
||||
#connect(ctx: PlayerContextValue<Store> | undefined): void {
|
||||
if (!ctx) return;
|
||||
|
||||
// Create StoreController with the store directly
|
||||
if (!this.#storeCtrl && this.#selector) {
|
||||
this.#storeCtrl = new StoreController(this.#host, ctx.store, this.#selector);
|
||||
if (!this.#store && this.#selector) {
|
||||
this.#store = new StoreController(this.#host, ctx.store, this.#selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import type { PropertyValues } from '@lit/reactive-element';
|
||||
import { PlayButtonCore } from '@videojs/core';
|
||||
import {
|
||||
applyElementProps,
|
||||
applyStateDataAttrs,
|
||||
createButton,
|
||||
logMissingFeature,
|
||||
selectPlayback,
|
||||
} from '@videojs/core/dom';
|
||||
|
||||
import { playerContext } from '../../player/context';
|
||||
import { PlayerController } from '../../player/player-controller';
|
||||
import { MediaElement } from '../media-element';
|
||||
|
||||
export class PlayButtonElement extends MediaElement {
|
||||
static readonly tagName = 'media-play-button';
|
||||
|
||||
static override properties = {
|
||||
label: { type: String },
|
||||
disabled: { type: Boolean },
|
||||
};
|
||||
|
||||
label = '';
|
||||
disabled = false;
|
||||
|
||||
readonly #core = new PlayButtonCore();
|
||||
readonly #state = new PlayerController(this, playerContext, selectPlayback);
|
||||
|
||||
#disconnect: AbortController | null = null;
|
||||
|
||||
override connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
this.#disconnect = new AbortController();
|
||||
|
||||
const buttonProps = createButton({
|
||||
onActivate: () => this.#core.toggle(this.#state.value!),
|
||||
isDisabled: () => this.disabled || !this.#state.value,
|
||||
});
|
||||
|
||||
applyElementProps(this, buttonProps, this.#disconnect.signal);
|
||||
}
|
||||
|
||||
override disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this.#disconnect?.abort();
|
||||
this.#disconnect = null;
|
||||
}
|
||||
|
||||
protected override willUpdate(changed: PropertyValues): void {
|
||||
super.willUpdate(changed);
|
||||
this.#core.setProps(this);
|
||||
}
|
||||
|
||||
protected override update(changed: PropertyValues): void {
|
||||
super.update(changed);
|
||||
|
||||
const state = this.#state.value;
|
||||
|
||||
if (!state) {
|
||||
logMissingFeature(PlayButtonElement.tagName, 'playback');
|
||||
return;
|
||||
}
|
||||
|
||||
applyElementProps(this, this.#core.getAttrs(state));
|
||||
applyStateDataAttrs(this, this.#core.getState(state));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user