mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
done
This commit is contained in:
@@ -12,7 +12,7 @@ module.exports = [
|
||||
sourcemap: true,
|
||||
},
|
||||
watch: {
|
||||
clearScreen: false
|
||||
clearScreen: false,
|
||||
},
|
||||
external: (id) => {
|
||||
// Don't externalize relative imports (starts with . or /)
|
||||
@@ -24,7 +24,7 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
resolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
}),
|
||||
commonjs(),
|
||||
typescript({
|
||||
@@ -43,7 +43,7 @@ module.exports = [
|
||||
sourcemap: true,
|
||||
},
|
||||
watch: {
|
||||
clearScreen: false
|
||||
clearScreen: false,
|
||||
},
|
||||
external: (id) => {
|
||||
// Don't externalize relative imports (starts with . or /)
|
||||
@@ -55,7 +55,7 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
resolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
}),
|
||||
commonjs(),
|
||||
typescript({
|
||||
|
||||
@@ -4,4 +4,4 @@ export * as MediaVolumeHighIcon from './media-volume-high-icon.js';
|
||||
export * as MediaVolumeLowIcon from './media-volume-low-icon.js';
|
||||
export * as MediaVolumeOffIcon from './media-volume-off-icon.js';
|
||||
export * as MediaFullscreenEnterIcon from './media-fullscreen-enter-icon.js';
|
||||
export * as MediaFullscreenExitIcon from './media-fullscreen-exit-icon.js';
|
||||
export * as MediaFullscreenExitIcon from './media-fullscreen-exit-icon.js';
|
||||
|
||||
@@ -23,4 +23,4 @@ export class MediaChromeIcon extends HTMLElement {
|
||||
this.shadowRoot!.innerHTML = (this.constructor as typeof MediaChromeIcon).getTemplateHTML();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
@@ -17,4 +18,4 @@ export class MediaFullscreenEnterIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-fullscreen-enter-icon', MediaFullscreenEnterIcon);
|
||||
customElements.define('media-fullscreen-enter-icon', MediaFullscreenEnterIcon);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
@@ -17,4 +18,4 @@ export class MediaFullscreenExitIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-fullscreen-exit-icon', MediaFullscreenExitIcon);
|
||||
customElements.define('media-fullscreen-exit-icon', MediaFullscreenExitIcon);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
@@ -12,4 +13,4 @@ export class MediaPauseIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-pause-icon', MediaPauseIcon);
|
||||
customElements.define('media-pause-icon', MediaPauseIcon);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
@@ -17,4 +18,4 @@ export class MediaPlayIcon extends MediaChromeIcon {
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
}
|
||||
|
||||
customElements.define('media-play-icon', MediaPlayIcon);
|
||||
customElements.define('media-play-icon', MediaPlayIcon);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
import { SVG_ICONS } from '@vjs-10/icons';
|
||||
|
||||
import { MediaChromeIcon } from './media-chrome-icon.js';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */ `
|
||||
${MediaChromeIcon.getTemplateHTML()}
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
"incremental": false
|
||||
},
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,4 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from './media-provider';
|
||||
export * from './media-provider';
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@ export default defineConfig({
|
||||
incremental: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
// Store integration utilities for HTML/Web Components
|
||||
// Store integration utilities for HTML/Web Components
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@ export default defineConfig({
|
||||
incremental: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ module.exports = [
|
||||
sourcemap: true,
|
||||
},
|
||||
watch: {
|
||||
clearScreen: false
|
||||
clearScreen: false,
|
||||
},
|
||||
external: (id) => {
|
||||
// Don't externalize relative imports (starts with . or /)
|
||||
@@ -24,7 +24,7 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
resolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
}),
|
||||
commonjs(),
|
||||
typescript({
|
||||
@@ -43,7 +43,7 @@ module.exports = [
|
||||
sourcemap: true,
|
||||
},
|
||||
watch: {
|
||||
clearScreen: false
|
||||
clearScreen: false,
|
||||
},
|
||||
external: (id) => {
|
||||
// Don't externalize relative imports (starts with . or /)
|
||||
@@ -55,7 +55,7 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
resolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
}),
|
||||
commonjs(),
|
||||
typescript({
|
||||
|
||||
@@ -3,7 +3,7 @@ import { namedNodeMapToObject } from '../utils/element-utils.js';
|
||||
export function getTemplateHTML(
|
||||
this: typeof MediaChromeButton,
|
||||
_attrs: Record<string, string>,
|
||||
_props: Record<string, any> = {},
|
||||
_props: Record<string, any> = {}
|
||||
) {
|
||||
return /* html */ `
|
||||
<style>
|
||||
@@ -31,20 +31,14 @@ export class MediaChromeButton extends HTMLElement {
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
// Set up the Shadow DOM if not using Declarative Shadow DOM.
|
||||
this.attachShadow(
|
||||
(this.constructor as typeof MediaChromeButton).shadowRootOptions,
|
||||
);
|
||||
this.attachShadow((this.constructor as typeof MediaChromeButton).shadowRootOptions);
|
||||
|
||||
const attrs = namedNodeMapToObject(this.attributes);
|
||||
const html = (
|
||||
this.constructor as typeof MediaChromeButton
|
||||
).getTemplateHTML(attrs);
|
||||
const html = (this.constructor as typeof MediaChromeButton).getTemplateHTML(attrs);
|
||||
// From MDN: setHTMLUnsafe should be used instead of ShadowRoot.innerHTML
|
||||
// when a string of HTML may contain declarative shadow roots.
|
||||
const shadowRoot = this.shadowRoot as unknown as ShadowRoot;
|
||||
shadowRoot.setHTMLUnsafe
|
||||
? shadowRoot.setHTMLUnsafe(html)
|
||||
: (shadowRoot.innerHTML = html);
|
||||
shadowRoot.setHTMLUnsafe ? shadowRoot.setHTMLUnsafe(html) : (shadowRoot.innerHTML = html);
|
||||
}
|
||||
|
||||
this.addEventListener('click', this);
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import {
|
||||
currentTimeDisplayStateDefinition,
|
||||
formatDisplayTime,
|
||||
} from '@vjs-10/media-store';
|
||||
import { currentTimeDisplayStateDefinition, formatDisplayTime } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
|
||||
export class CurrentTimeDisplayBase extends HTMLElement {
|
||||
static shadowRootOptions = {
|
||||
@@ -25,9 +19,7 @@ export class CurrentTimeDisplayBase extends HTMLElement {
|
||||
super();
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
this.attachShadow(
|
||||
(this.constructor as typeof CurrentTimeDisplayBase).shadowRootOptions,
|
||||
);
|
||||
this.attachShadow((this.constructor as typeof CurrentTimeDisplayBase).shadowRootOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +35,7 @@ export class CurrentTimeDisplayBase extends HTMLElement {
|
||||
return this.hasAttribute('show-remaining');
|
||||
}
|
||||
|
||||
attributeChangedCallback(
|
||||
name: string,
|
||||
_oldValue: string | null,
|
||||
_newValue: string | null,
|
||||
) {
|
||||
attributeChangedCallback(name: string, _oldValue: string | null, _newValue: string | null) {
|
||||
if (name === 'show-remaining' && this._state) {
|
||||
// Re-render with current state when show-remaining attribute changes
|
||||
this._update({}, this._state);
|
||||
@@ -104,16 +92,13 @@ export const CurrentTimeDisplay = toConnectedHTMLComponent(
|
||||
CurrentTimeDisplayBase,
|
||||
useCurrentTimeDisplayState,
|
||||
useCurrentTimeDisplayProps,
|
||||
'CurrentTimeDisplay',
|
||||
'CurrentTimeDisplay'
|
||||
);
|
||||
|
||||
// Register the custom element
|
||||
if (!globalThis.customElements.get('media-current-time-display')) {
|
||||
// @ts-ignore - Custom element constructor compatibility
|
||||
globalThis.customElements.define(
|
||||
'media-current-time-display',
|
||||
CurrentTimeDisplay,
|
||||
);
|
||||
globalThis.customElements.define('media-current-time-display', CurrentTimeDisplay);
|
||||
}
|
||||
|
||||
export default CurrentTimeDisplay;
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { durationDisplayStateDefinition, formatDisplayTime } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
import { namedNodeMapToObject } from '../utils/element-utils.js';
|
||||
|
||||
export function getTemplateHTML(
|
||||
this: typeof DurationDisplayBase,
|
||||
_attrs: Record<string, string>,
|
||||
_props: Record<string, any> = {},
|
||||
_props: Record<string, any> = {}
|
||||
) {
|
||||
return /* html */ `
|
||||
<span></span>
|
||||
@@ -32,18 +29,12 @@ export class DurationDisplayBase extends HTMLElement {
|
||||
super();
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
this.attachShadow(
|
||||
(this.constructor as typeof DurationDisplayBase).shadowRootOptions,
|
||||
);
|
||||
this.attachShadow((this.constructor as typeof DurationDisplayBase).shadowRootOptions);
|
||||
|
||||
const attrs = namedNodeMapToObject(this.attributes);
|
||||
const html = (
|
||||
this.constructor as typeof DurationDisplayBase
|
||||
).getTemplateHTML(attrs);
|
||||
const html = (this.constructor as typeof DurationDisplayBase).getTemplateHTML(attrs);
|
||||
const shadowRoot = this.shadowRoot as unknown as ShadowRoot;
|
||||
shadowRoot.setHTMLUnsafe
|
||||
? shadowRoot.setHTMLUnsafe(html)
|
||||
: (shadowRoot.innerHTML = html);
|
||||
shadowRoot.setHTMLUnsafe ? shadowRoot.setHTMLUnsafe(html) : (shadowRoot.innerHTML = html);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +44,7 @@ export class DurationDisplayBase extends HTMLElement {
|
||||
|
||||
_update(_props: any, state: any) {
|
||||
this._state = state;
|
||||
|
||||
|
||||
// Update the span content with formatted duration
|
||||
const spanElement = this.shadowRoot?.querySelector('span') as HTMLElement;
|
||||
if (spanElement) {
|
||||
@@ -95,7 +86,7 @@ export const DurationDisplay = toConnectedHTMLComponent(
|
||||
DurationDisplayBase,
|
||||
useDurationDisplayState,
|
||||
useDurationDisplayProps,
|
||||
'DurationDisplay',
|
||||
'DurationDisplay'
|
||||
);
|
||||
|
||||
// Register the custom element
|
||||
@@ -104,4 +95,4 @@ if (!globalThis.customElements.get('media-duration-display')) {
|
||||
globalThis.customElements.define('media-duration-display', DurationDisplay);
|
||||
}
|
||||
|
||||
export default DurationDisplay;
|
||||
export default DurationDisplay;
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { MediaChromeButton } from './media-chrome-button';
|
||||
import { fullscreenButtonStateDefinition } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
import { MediaChromeButton } from './media-chrome-button';
|
||||
|
||||
export class FullscreenButtonBase extends MediaChromeButton {
|
||||
_state:
|
||||
| {
|
||||
@@ -50,9 +47,7 @@ export const useFullscreenButtonState: StateHook<{ fullscreen: boolean }> = {
|
||||
keys: fullscreenButtonStateDefinition.keys,
|
||||
transform: (rawState, mediaStore) => ({
|
||||
...fullscreenButtonStateDefinition.stateTransform(rawState),
|
||||
...fullscreenButtonStateDefinition.createRequestMethods(
|
||||
mediaStore.dispatch,
|
||||
),
|
||||
...fullscreenButtonStateDefinition.createRequestMethods(mediaStore.dispatch),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -60,10 +55,7 @@ export const useFullscreenButtonState: StateHook<{ fullscreen: boolean }> = {
|
||||
* FullscreenButton props hook - equivalent to React's useFullscreenButtonProps
|
||||
* Handles element attributes and properties based on state
|
||||
*/
|
||||
export const useFullscreenButtonProps: PropsHook<{ fullscreen: boolean }> = (
|
||||
state,
|
||||
_element,
|
||||
) => {
|
||||
export const useFullscreenButtonProps: PropsHook<{ fullscreen: boolean }> = (state, _element) => {
|
||||
const baseProps: Record<string, any> = {
|
||||
/** data attributes/props */
|
||||
['data-fullscreen']: state.fullscreen,
|
||||
@@ -89,7 +81,7 @@ export const FullscreenButton = toConnectedHTMLComponent(
|
||||
FullscreenButtonBase,
|
||||
useFullscreenButtonState,
|
||||
useFullscreenButtonProps,
|
||||
'FullscreenButton',
|
||||
'FullscreenButton'
|
||||
);
|
||||
|
||||
// NOTE: In this architecture it will be important to decouple component class definitions from their registration in the CustomElementsRegistry. (CJP)
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { MediaChromeButton } from './media-chrome-button';
|
||||
import { muteButtonStateDefinition } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
import { MediaChromeButton } from './media-chrome-button';
|
||||
|
||||
export class MuteButtonBase extends MediaChromeButton {
|
||||
_state:
|
||||
| {
|
||||
@@ -99,7 +96,7 @@ export const MuteButton = toConnectedHTMLComponent(
|
||||
MuteButtonBase,
|
||||
useMuteButtonState,
|
||||
useMuteButtonProps,
|
||||
'MuteButton',
|
||||
'MuteButton'
|
||||
);
|
||||
|
||||
// NOTE: In this architecture it will be important to decouple component class definitions from their registration in the CustomElementsRegistry. (CJP)
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { MediaChromeButton } from './media-chrome-button';
|
||||
import { playButtonStateDefinition } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
import { MediaChromeButton } from './media-chrome-button';
|
||||
|
||||
export class PlayButtonBase extends MediaChromeButton {
|
||||
_state:
|
||||
| { paused: boolean; requestPlay: () => void; requestPause: () => void }
|
||||
| undefined;
|
||||
_state: { paused: boolean; requestPlay: () => void; requestPause: () => void } | undefined;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -58,10 +53,7 @@ export const usePlayButtonState: StateHook<{ paused: boolean }> = {
|
||||
* PlayButton props hook - equivalent to React's usePlayButtonProps
|
||||
* Handles element attributes and properties based on state
|
||||
*/
|
||||
export const usePlayButtonProps: PropsHook<{ paused: boolean }> = (
|
||||
state,
|
||||
_element,
|
||||
) => {
|
||||
export const usePlayButtonProps: PropsHook<{ paused: boolean }> = (state, _element) => {
|
||||
const baseProps: Record<string, any> = {
|
||||
/** data attributes/props */
|
||||
['data-paused']: state.paused,
|
||||
@@ -87,7 +79,7 @@ export const PlayButton = toConnectedHTMLComponent(
|
||||
PlayButtonBase,
|
||||
usePlayButtonState,
|
||||
usePlayButtonProps,
|
||||
'PlayButton',
|
||||
'PlayButton'
|
||||
);
|
||||
|
||||
// NOTE: In this architecture it will be important to decouple component class definitions from their registration in the CustomElementsRegistry. (CJP)
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { timeRangeStateDefinition } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
|
||||
// Utility functions for pointer position and seek time calculations
|
||||
const calculatePointerRatio = (clientX: number, rect: DOMRect): number => {
|
||||
const x = clientX - rect.left;
|
||||
@@ -15,10 +12,7 @@ const calculateSeekTimeFromRatio = (ratio: number, duration: number): number =>
|
||||
return (ratio / 100) * duration;
|
||||
};
|
||||
|
||||
const calculateSeekTimeFromPointerEvent = (
|
||||
event: PointerEvent,
|
||||
duration: number
|
||||
): number => {
|
||||
const calculateSeekTimeFromPointerEvent = (event: PointerEvent, duration: number): number => {
|
||||
const rect = (event.target as HTMLElement).getBoundingClientRect();
|
||||
const ratio = calculatePointerRatio(event.clientX, rect);
|
||||
return calculateSeekTimeFromRatio(ratio, duration);
|
||||
@@ -42,7 +36,7 @@ export class TimeRangeRootBase extends HTMLElement {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
||||
// Add pointer event listeners
|
||||
this.addEventListener('pointerdown', this);
|
||||
this.addEventListener('pointermove', this);
|
||||
@@ -80,7 +74,7 @@ export class TimeRangeRootBase extends HTMLElement {
|
||||
this._dragging = true;
|
||||
const seekTime = calculateSeekTimeFromPointerEvent(event, this._state!.duration);
|
||||
this._state!.requestSeek(seekTime);
|
||||
|
||||
|
||||
// Capture pointer events
|
||||
this.setPointerCapture(event.pointerId);
|
||||
}
|
||||
@@ -100,7 +94,7 @@ export class TimeRangeRootBase extends HTMLElement {
|
||||
|
||||
private _handlePointerUp(event: PointerEvent) {
|
||||
this.releasePointerCapture(event.pointerId);
|
||||
|
||||
|
||||
if (this._dragging && this._trackElement && this._pointerPosition !== null) {
|
||||
const seekTime = calculateSeekTimeFromRatio(this._pointerPosition, this._state!.duration);
|
||||
this._state!.requestSeek(seekTime);
|
||||
@@ -126,23 +120,23 @@ export class TimeRangeRootBase extends HTMLElement {
|
||||
|
||||
_update(props: any, state: any) {
|
||||
this._state = state;
|
||||
|
||||
|
||||
// Find track element
|
||||
this._trackElement = this.querySelector('media-time-range-track') as HTMLElement;
|
||||
|
||||
|
||||
// Calculate slider fill percentage
|
||||
const sliderFill = this._dragging && this._pointerPosition !== null
|
||||
? this._pointerPosition
|
||||
: state.duration > 0
|
||||
? (state.currentTime / state.duration) * 100
|
||||
: 0;
|
||||
const sliderFill =
|
||||
this._dragging && this._pointerPosition !== null
|
||||
? this._pointerPosition
|
||||
: state.duration > 0
|
||||
? (state.currentTime / state.duration) * 100
|
||||
: 0;
|
||||
|
||||
// Update CSS custom properties
|
||||
this.style.setProperty('--slider-fill', `${Math.round(sliderFill)}%`);
|
||||
this.style.setProperty('--slider-pointer',
|
||||
this._hovering && this._pointerPosition !== null
|
||||
? `${Math.round(this._pointerPosition)}%`
|
||||
: '0%'
|
||||
this.style.setProperty(
|
||||
'--slider-pointer',
|
||||
this._hovering && this._pointerPosition !== null ? `${Math.round(this._pointerPosition)}%` : '0%'
|
||||
);
|
||||
|
||||
// Update ARIA attributes
|
||||
@@ -152,7 +146,7 @@ export class TimeRangeRootBase extends HTMLElement {
|
||||
this.setAttribute('aria-valuemax', '100');
|
||||
this.setAttribute('aria-valuenow', sliderFill.toString());
|
||||
this.setAttribute('aria-valuetext', props['aria-valuetext'] || '');
|
||||
|
||||
|
||||
// Update data attributes
|
||||
this.setAttribute('data-current-time', state.currentTime.toString());
|
||||
this.setAttribute('data-duration', state.duration.toString());
|
||||
@@ -300,7 +294,7 @@ export const TimeRangeRoot = toConnectedHTMLComponent(
|
||||
TimeRangeRootBase,
|
||||
useTimeRangeRootState,
|
||||
useTimeRangeRootProps,
|
||||
'TimeRangeRoot',
|
||||
'TimeRangeRoot'
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -310,7 +304,7 @@ export const TimeRangeTrack = toConnectedHTMLComponent(
|
||||
TimeRangeTrackBase,
|
||||
{ keys: [], transform: () => ({}) },
|
||||
useTimeRangeTrackProps,
|
||||
'TimeRangeTrack',
|
||||
'TimeRangeTrack'
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -320,7 +314,7 @@ export const TimeRangeProgress = toConnectedHTMLComponent(
|
||||
TimeRangeProgressBase,
|
||||
{ keys: [], transform: () => ({}) },
|
||||
useTimeRangeProgressProps,
|
||||
'TimeRangeProgress',
|
||||
'TimeRangeProgress'
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -330,7 +324,7 @@ export const TimeRangePointer = toConnectedHTMLComponent(
|
||||
TimeRangePointerBase,
|
||||
{ keys: [], transform: () => ({}) },
|
||||
useTimeRangePointerProps,
|
||||
'TimeRangePointer',
|
||||
'TimeRangePointer'
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -340,7 +334,7 @@ export const TimeRangeThumb = toConnectedHTMLComponent(
|
||||
TimeRangeThumbBase,
|
||||
{ keys: [], transform: () => ({}) },
|
||||
useTimeRangeThumbProps,
|
||||
'TimeRangeThumb',
|
||||
'TimeRangeThumb'
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import {
|
||||
toConnectedHTMLComponent,
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { volumeRangeStateDefinition } from '@vjs-10/media-store';
|
||||
|
||||
import { PropsHook, StateHook, toConnectedHTMLComponent } from '../utils/component-factory';
|
||||
|
||||
export class VolumeRangeBase extends HTMLElement {
|
||||
_state:
|
||||
| {
|
||||
@@ -119,7 +116,7 @@ export const VolumeRange = toConnectedHTMLComponent(
|
||||
VolumeRangeBase,
|
||||
useVolumeRangeState,
|
||||
useVolumeRangeProps,
|
||||
'VolumeRange',
|
||||
'VolumeRange'
|
||||
);
|
||||
|
||||
// NOTE: In this architecture it will be important to decouple component class definitions from their registration in the CustomElementsRegistry. (CJP)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ConsumerMixin } from '@open-wc/context-protocol';
|
||||
|
||||
export function getTemplateHTML() {
|
||||
return /* html */`
|
||||
return /* html */ `
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
`;
|
||||
|
||||
@@ -26,7 +26,7 @@ export const toConnectedHTMLComponent = <TState = any>(
|
||||
BaseClass: CustomElementConstructor,
|
||||
stateHook: StateHook<TState>,
|
||||
propsHook: PropsHook<TState>,
|
||||
displayName?: string,
|
||||
displayName?: string
|
||||
) => {
|
||||
const ConnectedComponent = class extends ConsumerMixin(BaseClass) {
|
||||
static get observedAttributes(): string[] {
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
"incremental": false
|
||||
},
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user