@videojs/html 0.1.0-preview.2 → 0.1.0-preview.4
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/README.md +2 -2
- package/dist/button-D1DWjsQu.js +57 -0
- package/dist/button-D1DWjsQu.js.map +1 -0
- package/dist/component-factory-DeAN6cjC.js +47 -0
- package/dist/component-factory-DeAN6cjC.js.map +1 -0
- package/dist/current-time-display-C3qndGf5.js +47 -0
- package/dist/current-time-display-C3qndGf5.js.map +1 -0
- package/dist/custom-element-3bDlB2XO.js +10 -0
- package/dist/custom-element-3bDlB2XO.js.map +1 -0
- package/dist/define/index.d.ts +12 -0
- package/dist/define/index.js +27 -0
- package/dist/define/media-container.d.ts +1 -0
- package/dist/define/media-container.js +3 -0
- package/dist/define/media-current-time-display.d.ts +1 -0
- package/dist/define/media-current-time-display.js +4 -0
- package/dist/define/media-duration-display.d.ts +1 -0
- package/dist/define/media-duration-display.js +4 -0
- package/dist/define/media-fullscreen-button.d.ts +1 -0
- package/dist/define/media-fullscreen-button.js +5 -0
- package/dist/define/media-mute-button.d.ts +1 -0
- package/dist/define/media-mute-button.js +5 -0
- package/dist/define/media-play-button.d.ts +1 -0
- package/dist/define/media-play-button.js +5 -0
- package/dist/define/media-popover.d.ts +1 -0
- package/dist/define/media-popover.js +3 -0
- package/dist/define/media-preview-time-display.d.ts +1 -0
- package/dist/define/media-preview-time-display.js +4 -0
- package/dist/define/media-provider.d.ts +1 -0
- package/dist/define/media-provider.js +3 -0
- package/dist/define/media-time-slider.d.ts +1 -0
- package/dist/define/media-time-slider.js +4 -0
- package/dist/define/media-tooltip.d.ts +1 -0
- package/dist/define/media-tooltip.js +3 -0
- package/dist/define/media-volume-slider.d.ts +1 -0
- package/dist/define/media-volume-slider.js +4 -0
- package/dist/duration-display-JOPp3bdU.js +49 -0
- package/dist/duration-display-JOPp3bdU.js.map +1 -0
- package/dist/fullscreen-button-CGO2UJjs.js +48 -0
- package/dist/fullscreen-button-CGO2UJjs.js.map +1 -0
- package/dist/{icons-YlVTDFdV.js → icons-CuxuONCk.js} +59 -48
- package/dist/icons-CuxuONCk.js.map +1 -0
- package/dist/icons.d.ts +1 -2
- package/dist/icons.js +2 -3
- package/dist/index-LKrIp3Oo.d.ts +1 -0
- package/dist/index.d.ts +172 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -9
- package/dist/media-container-BGEXSi9g.js +8 -0
- package/dist/media-container-BGEXSi9g.js.map +1 -0
- package/dist/media-container-C0MUzkJ_.js +83 -0
- package/dist/media-container-C0MUzkJ_.js.map +1 -0
- package/dist/media-container-DPnFjmtK.d.ts +1 -0
- package/dist/media-current-time-display-B-4Cp845.js +8 -0
- package/dist/media-current-time-display-B-4Cp845.js.map +1 -0
- package/dist/media-current-time-display-Cd0rPAuj.d.ts +1 -0
- package/dist/media-duration-display-BLMr7VHo.js +8 -0
- package/dist/media-duration-display-BLMr7VHo.js.map +1 -0
- package/dist/media-duration-display-qvm6YX-q.d.ts +1 -0
- package/dist/media-fullscreen-button-BgUK3lgu.d.ts +1 -0
- package/dist/media-fullscreen-button-Dcflbt54.js +8 -0
- package/dist/media-fullscreen-button-Dcflbt54.js.map +1 -0
- package/dist/media-mute-button-BOVhZ3aP.js +8 -0
- package/dist/media-mute-button-BOVhZ3aP.js.map +1 -0
- package/dist/media-mute-button-NVJF2EEW.d.ts +1 -0
- package/dist/media-play-button-CLj-hkwn.js +8 -0
- package/dist/media-play-button-CLj-hkwn.js.map +1 -0
- package/dist/media-play-button-oq8yDlxe.d.ts +1 -0
- package/dist/media-popover-BtJmPv0E.d.ts +1 -0
- package/dist/media-popover-F4M4Tq4z.js +8 -0
- package/dist/media-popover-F4M4Tq4z.js.map +1 -0
- package/dist/media-preview-time-display-4YX5Rics.d.ts +1 -0
- package/dist/media-preview-time-display-DAiMgLPX.js +8 -0
- package/dist/media-preview-time-display-DAiMgLPX.js.map +1 -0
- package/dist/media-provider-CyoL0bCx.js +17 -0
- package/dist/media-provider-CyoL0bCx.js.map +1 -0
- package/dist/media-provider-D7P2TLXG.d.ts +1 -0
- package/dist/media-provider-D_GL2_DN.js +8 -0
- package/dist/media-provider-D_GL2_DN.js.map +1 -0
- package/dist/media-skin-Di3vSHvS.d.ts +11 -0
- package/dist/media-skin-Di3vSHvS.d.ts.map +1 -0
- package/dist/media-skin-mHWwUPg3.js +36 -0
- package/dist/media-skin-mHWwUPg3.js.map +1 -0
- package/dist/media-time-slider-Bp2qnwsW.js +12 -0
- package/dist/media-time-slider-Bp2qnwsW.js.map +1 -0
- package/dist/media-time-slider-DvMnfYXZ.d.ts +1 -0
- package/dist/media-tooltip-BqV17mdM.d.ts +1 -0
- package/dist/media-tooltip-ClcVafMb.js +14 -0
- package/dist/media-tooltip-ClcVafMb.js.map +1 -0
- package/dist/media-volume-slider-CKSxmdQv.js +11 -0
- package/dist/media-volume-slider-CKSxmdQv.js.map +1 -0
- package/dist/media-volume-slider-DP47VLVi.d.ts +1 -0
- package/dist/mute-button-vW2sLqqY.js +50 -0
- package/dist/mute-button-vW2sLqqY.js.map +1 -0
- package/dist/play-button-aVb0g10G.js +44 -0
- package/dist/play-button-aVb0g10G.js.map +1 -0
- package/dist/popover-Dc0hyhwB.js +187 -0
- package/dist/popover-Dc0hyhwB.js.map +1 -0
- package/dist/preview-time-display-Dax0FQ2X.js +44 -0
- package/dist/preview-time-display-Dax0FQ2X.js.map +1 -0
- package/dist/skins/frosted.d.ts +23 -0
- package/dist/skins/frosted.d.ts.map +1 -0
- package/dist/skins/frosted.js +144 -0
- package/dist/skins/frosted.js.map +1 -0
- package/dist/skins/minimal.d.ts +23 -0
- package/dist/skins/minimal.d.ts.map +1 -0
- package/dist/skins/minimal.js +149 -0
- package/dist/skins/minimal.js.map +1 -0
- package/dist/time-slider-CA1GMs6A.js +201 -0
- package/dist/time-slider-CA1GMs6A.js.map +1 -0
- package/dist/tooltip-54fBUUpb.js +296 -0
- package/dist/tooltip-54fBUUpb.js.map +1 -0
- package/dist/volume-slider-guD8gqpi.js +206 -0
- package/dist/volume-slider-guD8gqpi.js.map +1 -0
- package/package.json +16 -7
- package/dist/chunk-Bp6m_JJh.js +0 -13
- package/dist/icons-YlVTDFdV.js.map +0 -1
- package/dist/index-BtSCzZKn.d.ts +0 -62
- package/dist/index-BtSCzZKn.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/media-skin-BlXPC9wG.js +0 -1458
- package/dist/media-skin-BlXPC9wG.js.map +0 -1
- package/dist/media-skin-CbuyuCb-.d.ts +0 -208
- package/dist/media-skin-CbuyuCb-.d.ts.map +0 -1
- package/dist/skins/default.d.ts +0 -12
- package/dist/skins/default.d.ts.map +0 -1
- package/dist/skins/default.js +0 -424
- package/dist/skins/default.js.map +0 -1
|
@@ -1,1458 +0,0 @@
|
|
|
1
|
-
import { createMediaStore, currentTimeDisplayStateDefinition, durationDisplayStateDefinition, fullscreenButtonStateDefinition, muteButtonStateDefinition, playButtonStateDefinition, timeSliderStateDefinition, volumeSliderStateDefinition } from "@videojs/core/store";
|
|
2
|
-
import { formatDisplayTime, uniqueId } from "@videojs/utils";
|
|
3
|
-
import { ConsumerMixin, ProviderMixin } from "@open-wc/context-protocol";
|
|
4
|
-
import { getDocument, getNextTabbable, getPreviousTabbable, isOutsideEvent, namedNodeMapToObject, setAttributes } from "@videojs/utils/dom";
|
|
5
|
-
import { arrow, autoUpdate, computePosition, flip, offset, shift } from "@floating-ui/dom";
|
|
6
|
-
import { TimeSlider, VolumeSlider } from "@videojs/core";
|
|
7
|
-
|
|
8
|
-
//#region src/utils/component-factory.ts
|
|
9
|
-
/**
|
|
10
|
-
* Generic factory function to create connected HTML components using hooks pattern.
|
|
11
|
-
* Provides equivalent functionality to React's toConnectedComponent but for custom elements.
|
|
12
|
-
*
|
|
13
|
-
* @param BaseClass - Base custom element class to extend
|
|
14
|
-
* @param stateHook - Hook that defines state keys and transformation logic
|
|
15
|
-
* @param propsHook - Hook that handles element attributes and properties based on state
|
|
16
|
-
* @param eventsHook - Hook that defines event handling logic
|
|
17
|
-
* @param displayName - Display name for debugging
|
|
18
|
-
* @returns Connected custom element class with media store integration
|
|
19
|
-
*/
|
|
20
|
-
function toConnectedHTMLComponent(BaseClass, stateHook, propsHook, displayName) {
|
|
21
|
-
const ConnectedComponent = class extends ConsumerMixin(BaseClass) {
|
|
22
|
-
constructor(..._args) {
|
|
23
|
-
super(..._args);
|
|
24
|
-
this.contexts = { mediaStore: (mediaStore) => {
|
|
25
|
-
this._mediaStore = mediaStore;
|
|
26
|
-
this._mediaStore.subscribeKeys(stateHook.keys, (rawState) => {
|
|
27
|
-
const state = stateHook.transform(rawState, mediaStore);
|
|
28
|
-
const props = propsHook(state ?? {}, this);
|
|
29
|
-
this._update(props, state, mediaStore);
|
|
30
|
-
});
|
|
31
|
-
} };
|
|
32
|
-
}
|
|
33
|
-
static get observedAttributes() {
|
|
34
|
-
return [...super.observedAttributes ?? []];
|
|
35
|
-
}
|
|
36
|
-
connectedCallback() {
|
|
37
|
-
super.connectedCallback?.();
|
|
38
|
-
}
|
|
39
|
-
disconnectedCallback() {
|
|
40
|
-
super.disconnectedCallback?.();
|
|
41
|
-
}
|
|
42
|
-
handleEvent(event) {
|
|
43
|
-
super.handleEvent?.(event);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
if (displayName) Object.defineProperty(ConnectedComponent, "name", { value: displayName });
|
|
47
|
-
return ConnectedComponent;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
//#endregion
|
|
51
|
-
//#region src/components/media-current-time-display.ts
|
|
52
|
-
var CurrentTimeDisplayBase = class extends HTMLElement {
|
|
53
|
-
static {
|
|
54
|
-
this.shadowRootOptions = { mode: "open" };
|
|
55
|
-
}
|
|
56
|
-
static {
|
|
57
|
-
this.observedAttributes = ["show-remaining"];
|
|
58
|
-
}
|
|
59
|
-
constructor() {
|
|
60
|
-
super();
|
|
61
|
-
if (!this.shadowRoot) this.attachShadow(this.constructor.shadowRootOptions);
|
|
62
|
-
}
|
|
63
|
-
get currentTime() {
|
|
64
|
-
return this._state?.currentTime ?? 0;
|
|
65
|
-
}
|
|
66
|
-
get duration() {
|
|
67
|
-
return this._state?.duration ?? 0;
|
|
68
|
-
}
|
|
69
|
-
get showRemaining() {
|
|
70
|
-
return this.hasAttribute("show-remaining");
|
|
71
|
-
}
|
|
72
|
-
attributeChangedCallback(name, _oldValue, _newValue) {
|
|
73
|
-
if (name === "show-remaining" && this._state) this._update({}, this._state);
|
|
74
|
-
}
|
|
75
|
-
_update(_props, state) {
|
|
76
|
-
this._state = state;
|
|
77
|
-
/** @TODO Should this live here or elsewhere? (CJP) */
|
|
78
|
-
const timeLabel = this.showRemaining && state.duration != null && state.currentTime != null ? formatDisplayTime(-(state.duration - state.currentTime)) : formatDisplayTime(state.currentTime);
|
|
79
|
-
if (this.shadowRoot) this.shadowRoot.textContent = timeLabel;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
const useCurrentTimeDisplayState = {
|
|
83
|
-
keys: [...currentTimeDisplayStateDefinition.keys],
|
|
84
|
-
transform: (rawState, _mediaStore) => ({ ...currentTimeDisplayStateDefinition.stateTransform(rawState) })
|
|
85
|
-
};
|
|
86
|
-
const getCurrentTimeDisplayProps = (_state, _element) => {
|
|
87
|
-
return {};
|
|
88
|
-
};
|
|
89
|
-
const CurrentTimeDisplay = toConnectedHTMLComponent(CurrentTimeDisplayBase, useCurrentTimeDisplayState, getCurrentTimeDisplayProps, "CurrentTimeDisplay");
|
|
90
|
-
if (!globalThis.customElements.get("media-current-time-display")) globalThis.customElements.define("media-current-time-display", CurrentTimeDisplay);
|
|
91
|
-
|
|
92
|
-
//#endregion
|
|
93
|
-
//#region src/components/media-duration-display.ts
|
|
94
|
-
function getTemplateHTML$3(_attrs, _props = {}) {
|
|
95
|
-
return `
|
|
96
|
-
<span></span>
|
|
97
|
-
`;
|
|
98
|
-
}
|
|
99
|
-
var DurationDisplayBase = class extends HTMLElement {
|
|
100
|
-
static {
|
|
101
|
-
this.shadowRootOptions = { mode: "open" };
|
|
102
|
-
}
|
|
103
|
-
static {
|
|
104
|
-
this.getTemplateHTML = getTemplateHTML$3;
|
|
105
|
-
}
|
|
106
|
-
constructor() {
|
|
107
|
-
super();
|
|
108
|
-
if (!this.shadowRoot) {
|
|
109
|
-
this.attachShadow(this.constructor.shadowRootOptions);
|
|
110
|
-
const attrs = namedNodeMapToObject(this.attributes);
|
|
111
|
-
const html = this.constructor.getTemplateHTML(attrs);
|
|
112
|
-
const shadowRoot = this.shadowRoot;
|
|
113
|
-
shadowRoot.setHTMLUnsafe ? shadowRoot.setHTMLUnsafe(html) : shadowRoot.innerHTML = html;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
get duration() {
|
|
117
|
-
return this._state?.duration ?? 0;
|
|
118
|
-
}
|
|
119
|
-
_update(_props, state) {
|
|
120
|
-
this._state = state;
|
|
121
|
-
const spanElement = this.shadowRoot?.querySelector("span");
|
|
122
|
-
if (spanElement) spanElement.textContent = formatDisplayTime(state.duration);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
const useDurationDisplayState = {
|
|
126
|
-
keys: [...durationDisplayStateDefinition.keys],
|
|
127
|
-
transform: (rawState, _mediaStore) => ({ ...durationDisplayStateDefinition.stateTransform(rawState) })
|
|
128
|
-
};
|
|
129
|
-
const getDurationDisplayProps = (_state, _element) => {
|
|
130
|
-
return {};
|
|
131
|
-
};
|
|
132
|
-
const DurationDisplay = toConnectedHTMLComponent(DurationDisplayBase, useDurationDisplayState, getDurationDisplayProps, "DurationDisplay");
|
|
133
|
-
if (!globalThis.customElements.get("media-duration-display")) globalThis.customElements.define("media-duration-display", DurationDisplay);
|
|
134
|
-
|
|
135
|
-
//#endregion
|
|
136
|
-
//#region src/components/media-chrome-button.ts
|
|
137
|
-
function getTemplateHTML$2(_attrs, _props = {}) {
|
|
138
|
-
return `
|
|
139
|
-
<style>
|
|
140
|
-
/*
|
|
141
|
-
NOTE: Even though primitives should aim to be "unstyled" in their core definitions, we should
|
|
142
|
-
still add pointer-events, as this defines functionality. (CJP)
|
|
143
|
-
*/
|
|
144
|
-
:host {
|
|
145
|
-
pointer-events: auto;
|
|
146
|
-
}
|
|
147
|
-
</style>
|
|
148
|
-
<slot>
|
|
149
|
-
</slot>
|
|
150
|
-
`;
|
|
151
|
-
}
|
|
152
|
-
var MediaChromeButton = class extends HTMLElement {
|
|
153
|
-
static {
|
|
154
|
-
this.shadowRootOptions = { mode: "open" };
|
|
155
|
-
}
|
|
156
|
-
static {
|
|
157
|
-
this.getTemplateHTML = getTemplateHTML$2;
|
|
158
|
-
}
|
|
159
|
-
constructor() {
|
|
160
|
-
super();
|
|
161
|
-
if (!this.shadowRoot) {
|
|
162
|
-
this.attachShadow(this.constructor.shadowRootOptions);
|
|
163
|
-
const attrs = namedNodeMapToObject(this.attributes);
|
|
164
|
-
const html = this.constructor.getTemplateHTML(attrs);
|
|
165
|
-
const shadowRoot = this.shadowRoot;
|
|
166
|
-
shadowRoot.setHTMLUnsafe ? shadowRoot.setHTMLUnsafe(html) : shadowRoot.innerHTML = html;
|
|
167
|
-
}
|
|
168
|
-
this.addEventListener("click", this);
|
|
169
|
-
this.addEventListener("keydown", this);
|
|
170
|
-
}
|
|
171
|
-
handleEvent(event) {
|
|
172
|
-
const { type } = event;
|
|
173
|
-
if (type === "keydown") this.#handleKeyDown(event);
|
|
174
|
-
}
|
|
175
|
-
#handleKeyDown = (event) => {
|
|
176
|
-
const { metaKey, altKey, key } = event;
|
|
177
|
-
if (metaKey || altKey || !["Enter", " "].includes(key)) {
|
|
178
|
-
this.removeEventListener("keyup", this.#handleKeyUp);
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
this.addEventListener("keyup", this.#handleKeyUp, { once: true });
|
|
182
|
-
};
|
|
183
|
-
#handleKeyUp = (_event) => {
|
|
184
|
-
this.handleEvent({ type: "click" });
|
|
185
|
-
};
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
//#endregion
|
|
189
|
-
//#region src/components/media-fullscreen-button.ts
|
|
190
|
-
var FullscreenButtonBase = class extends MediaChromeButton {
|
|
191
|
-
handleEvent(event) {
|
|
192
|
-
super.handleEvent(event);
|
|
193
|
-
const { type } = event;
|
|
194
|
-
const state = this._state;
|
|
195
|
-
if (state && type === "click") if (state.fullscreen) state.requestExitFullscreen();
|
|
196
|
-
else state.requestEnterFullscreen();
|
|
197
|
-
}
|
|
198
|
-
get fullscreen() {
|
|
199
|
-
return this._state?.fullscreen ?? false;
|
|
200
|
-
}
|
|
201
|
-
_update(props, state, _mediaStore) {
|
|
202
|
-
this._state = state;
|
|
203
|
-
/** @TODO Follow up with React vs. W.C. data-* attributes discrepancies (CJP) */
|
|
204
|
-
setAttributes(this, props);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
/**
|
|
208
|
-
* FullscreenButton state hook - equivalent to React's useFullscreenButtonState
|
|
209
|
-
* Handles media store state subscription and transformation
|
|
210
|
-
*/
|
|
211
|
-
const getFullscreenButtonState = {
|
|
212
|
-
keys: fullscreenButtonStateDefinition.keys,
|
|
213
|
-
transform: (rawState, mediaStore) => ({
|
|
214
|
-
...fullscreenButtonStateDefinition.stateTransform(rawState),
|
|
215
|
-
...fullscreenButtonStateDefinition.createRequestMethods(mediaStore.dispatch)
|
|
216
|
-
})
|
|
217
|
-
};
|
|
218
|
-
const getFullscreenButtonProps = (state, _element) => {
|
|
219
|
-
return {
|
|
220
|
-
"data-fullscreen": state.fullscreen,
|
|
221
|
-
role: "button",
|
|
222
|
-
tabindex: "0",
|
|
223
|
-
"aria-label": state.fullscreen ? "exit fullscreen" : "enter fullscreen",
|
|
224
|
-
"data-tooltip": state.fullscreen ? "Exit Fullscreen" : "Enter Fullscreen"
|
|
225
|
-
};
|
|
226
|
-
};
|
|
227
|
-
const FullscreenButton = toConnectedHTMLComponent(FullscreenButtonBase, getFullscreenButtonState, getFullscreenButtonProps, "FullscreenButton");
|
|
228
|
-
if (!globalThis.customElements.get("media-fullscreen-button")) globalThis.customElements.define("media-fullscreen-button", FullscreenButton);
|
|
229
|
-
|
|
230
|
-
//#endregion
|
|
231
|
-
//#region src/components/media-mute-button.ts
|
|
232
|
-
var MuteButtonBase = class extends MediaChromeButton {
|
|
233
|
-
handleEvent(event) {
|
|
234
|
-
super.handleEvent(event);
|
|
235
|
-
const { type } = event;
|
|
236
|
-
const state = this._state;
|
|
237
|
-
if (state) {
|
|
238
|
-
if (type === "click") if (state.volumeLevel === "off") state.requestUnmute();
|
|
239
|
-
else state.requestMute();
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
get muted() {
|
|
243
|
-
return this._state?.muted ?? false;
|
|
244
|
-
}
|
|
245
|
-
get volumeLevel() {
|
|
246
|
-
return this._state?.volumeLevel ?? "high";
|
|
247
|
-
}
|
|
248
|
-
_update(props, state) {
|
|
249
|
-
this._state = state;
|
|
250
|
-
/** @TODO Follow up with React vs. W.C. data-* attributes discrepancies (CJP) */
|
|
251
|
-
setAttributes(this, props);
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
const getMuteButtonState = {
|
|
255
|
-
keys: muteButtonStateDefinition.keys,
|
|
256
|
-
transform: (rawState, mediaStore) => ({
|
|
257
|
-
...muteButtonStateDefinition.stateTransform(rawState),
|
|
258
|
-
...muteButtonStateDefinition.createRequestMethods(mediaStore.dispatch)
|
|
259
|
-
})
|
|
260
|
-
};
|
|
261
|
-
const getMuteButtonProps = (state, _element) => {
|
|
262
|
-
return {
|
|
263
|
-
"data-muted": state.muted,
|
|
264
|
-
"data-volume-level": state.volumeLevel,
|
|
265
|
-
role: "button",
|
|
266
|
-
tabindex: "0",
|
|
267
|
-
"aria-label": state.muted ? "unmute" : "mute",
|
|
268
|
-
"data-tooltip": state.muted ? "Unmute" : "Mute"
|
|
269
|
-
};
|
|
270
|
-
};
|
|
271
|
-
const MuteButton = toConnectedHTMLComponent(MuteButtonBase, getMuteButtonState, getMuteButtonProps, "MuteButton");
|
|
272
|
-
if (!globalThis.customElements.get("media-mute-button")) globalThis.customElements.define("media-mute-button", MuteButton);
|
|
273
|
-
|
|
274
|
-
//#endregion
|
|
275
|
-
//#region src/components/media-play-button.ts
|
|
276
|
-
var PlayButtonBase = class extends MediaChromeButton {
|
|
277
|
-
handleEvent(event) {
|
|
278
|
-
super.handleEvent(event);
|
|
279
|
-
const { type } = event;
|
|
280
|
-
const state = this._state;
|
|
281
|
-
if (state && type === "click") if (state.paused) state.requestPlay();
|
|
282
|
-
else state.requestPause();
|
|
283
|
-
}
|
|
284
|
-
get paused() {
|
|
285
|
-
return this._state?.paused ?? true;
|
|
286
|
-
}
|
|
287
|
-
_update(props, state, _mediaStore) {
|
|
288
|
-
this._state = state;
|
|
289
|
-
/** @TODO Follow up with React vs. W.C. data-* attributes discrepancies (CJP) */
|
|
290
|
-
setAttributes(this, props);
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
const getPlayButtonState = {
|
|
294
|
-
keys: playButtonStateDefinition.keys,
|
|
295
|
-
transform: (rawState, mediaStore) => ({
|
|
296
|
-
...playButtonStateDefinition.stateTransform(rawState),
|
|
297
|
-
...playButtonStateDefinition.createRequestMethods(mediaStore.dispatch)
|
|
298
|
-
})
|
|
299
|
-
};
|
|
300
|
-
const getPlayButtonProps = (state, _element) => {
|
|
301
|
-
return {
|
|
302
|
-
"data-paused": state.paused,
|
|
303
|
-
role: "button",
|
|
304
|
-
tabindex: "0",
|
|
305
|
-
"aria-label": state.paused ? "play" : "pause",
|
|
306
|
-
"data-tooltip": state.paused ? "Play" : "Pause"
|
|
307
|
-
};
|
|
308
|
-
};
|
|
309
|
-
const PlayButton = toConnectedHTMLComponent(PlayButtonBase, getPlayButtonState, getPlayButtonProps, "PlayButton");
|
|
310
|
-
if (!globalThis.customElements.get("media-play-button")) globalThis.customElements.define("media-play-button", PlayButton);
|
|
311
|
-
|
|
312
|
-
//#endregion
|
|
313
|
-
//#region src/components/media-popover.ts
|
|
314
|
-
var MediaPopoverRoot = class extends HTMLElement {
|
|
315
|
-
#open = false;
|
|
316
|
-
#hoverTimeout = null;
|
|
317
|
-
#cleanup = null;
|
|
318
|
-
#transitionStatus = "initial";
|
|
319
|
-
#abortController = null;
|
|
320
|
-
connectedCallback() {
|
|
321
|
-
this.#updateVisibility();
|
|
322
|
-
this.#abortController ??= new AbortController();
|
|
323
|
-
const { signal } = this.#abortController;
|
|
324
|
-
this.addEventListener("mouseenter", this, { signal });
|
|
325
|
-
this.addEventListener("mouseleave", this, { signal });
|
|
326
|
-
this.addEventListener("focusin", this, { signal });
|
|
327
|
-
this.addEventListener("focusout", this, { signal });
|
|
328
|
-
getDocument(this).documentElement.addEventListener("mouseleave", this, { signal });
|
|
329
|
-
}
|
|
330
|
-
disconnectedCallback() {
|
|
331
|
-
this.#clearHoverTimeout();
|
|
332
|
-
this.#cleanup?.();
|
|
333
|
-
this.#transitionStatus = "unmounted";
|
|
334
|
-
this.#updateVisibility();
|
|
335
|
-
this.#abortController?.abort();
|
|
336
|
-
this.#abortController = null;
|
|
337
|
-
}
|
|
338
|
-
handleEvent(event) {
|
|
339
|
-
switch (event.type) {
|
|
340
|
-
case "mouseenter":
|
|
341
|
-
this.#handleMouseEnter();
|
|
342
|
-
break;
|
|
343
|
-
case "mouseleave":
|
|
344
|
-
this.#handleMouseLeave(event);
|
|
345
|
-
break;
|
|
346
|
-
case "focusin":
|
|
347
|
-
this.#handleFocusIn(event);
|
|
348
|
-
break;
|
|
349
|
-
case "focusout":
|
|
350
|
-
this.#handleFocusOut(event);
|
|
351
|
-
break;
|
|
352
|
-
default: break;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
static get observedAttributes() {
|
|
356
|
-
return [
|
|
357
|
-
"open-on-hover",
|
|
358
|
-
"delay",
|
|
359
|
-
"close-delay"
|
|
360
|
-
];
|
|
361
|
-
}
|
|
362
|
-
get openOnHover() {
|
|
363
|
-
return this.hasAttribute("open-on-hover");
|
|
364
|
-
}
|
|
365
|
-
get delay() {
|
|
366
|
-
return Number.parseInt(this.getAttribute("delay") ?? "0", 10);
|
|
367
|
-
}
|
|
368
|
-
get closeDelay() {
|
|
369
|
-
return Number.parseInt(this.getAttribute("close-delay") ?? "0", 10);
|
|
370
|
-
}
|
|
371
|
-
get #triggerElement() {
|
|
372
|
-
return this.querySelector("media-popover-trigger");
|
|
373
|
-
}
|
|
374
|
-
get #portalElement() {
|
|
375
|
-
return this.querySelector("media-popover-portal");
|
|
376
|
-
}
|
|
377
|
-
get #positionerElement() {
|
|
378
|
-
return this.#portalElement?.querySelector("media-popover-positioner");
|
|
379
|
-
}
|
|
380
|
-
get #popupElement() {
|
|
381
|
-
return this.#portalElement?.querySelector("media-popover-popup");
|
|
382
|
-
}
|
|
383
|
-
setOpen(open) {
|
|
384
|
-
if (this.#open === open) return;
|
|
385
|
-
this.#open = open;
|
|
386
|
-
if (open) {
|
|
387
|
-
this.#setupFloating();
|
|
388
|
-
this.#portalElement?.renderGuards();
|
|
389
|
-
} else {
|
|
390
|
-
this.#portalElement?.removeGuards();
|
|
391
|
-
this.#cleanup?.();
|
|
392
|
-
this.#cleanup = null;
|
|
393
|
-
}
|
|
394
|
-
if (open) {
|
|
395
|
-
this.#transitionStatus = "initial";
|
|
396
|
-
requestAnimationFrame(() => {
|
|
397
|
-
this.#transitionStatus = "open";
|
|
398
|
-
this.#updateVisibility();
|
|
399
|
-
});
|
|
400
|
-
} else this.#transitionStatus = "close";
|
|
401
|
-
this.#updateVisibility();
|
|
402
|
-
}
|
|
403
|
-
#updateVisibility() {
|
|
404
|
-
this.style.display = "contents";
|
|
405
|
-
if (this.#popupElement) {
|
|
406
|
-
const placement = this.#positionerElement?.side ?? "top";
|
|
407
|
-
this.#popupElement.setAttribute("data-side", placement);
|
|
408
|
-
this.#popupElement.toggleAttribute("data-starting-style", this.#transitionStatus === "initial");
|
|
409
|
-
this.#popupElement.toggleAttribute("data-open", this.#transitionStatus === "initial" || this.#transitionStatus === "open");
|
|
410
|
-
this.#popupElement.toggleAttribute("data-ending-style", this.#transitionStatus === "close" || this.#transitionStatus === "unmounted");
|
|
411
|
-
this.#popupElement.toggleAttribute("data-closed", this.#transitionStatus === "close" || this.#transitionStatus === "unmounted");
|
|
412
|
-
this.#abortController ??= new AbortController();
|
|
413
|
-
const { signal } = this.#abortController;
|
|
414
|
-
this.#popupElement.addEventListener("mouseleave", this, { signal });
|
|
415
|
-
}
|
|
416
|
-
const triggerElement = this.#triggerElement?.firstElementChild;
|
|
417
|
-
if (triggerElement) {
|
|
418
|
-
triggerElement.setAttribute("aria-expanded", this.#open.toString());
|
|
419
|
-
triggerElement.toggleAttribute("data-popup-open", this.#open);
|
|
420
|
-
if (this.#popupElement?.id) triggerElement.setAttribute("aria-controls", this.#popupElement?.id);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
#setupFloating() {
|
|
424
|
-
if (!this.#triggerElement || !this.#popupElement) return;
|
|
425
|
-
const trigger = this.#triggerElement.firstElementChild;
|
|
426
|
-
const popup = this.#popupElement;
|
|
427
|
-
if (!trigger || !popup) return;
|
|
428
|
-
const placement = this.#positionerElement?.side ?? "top";
|
|
429
|
-
const sideOffset = this.#positionerElement?.sideOffset;
|
|
430
|
-
const updatePosition = () => {
|
|
431
|
-
computePosition(trigger, popup, {
|
|
432
|
-
placement,
|
|
433
|
-
middleware: [
|
|
434
|
-
offset(sideOffset),
|
|
435
|
-
flip(),
|
|
436
|
-
shift()
|
|
437
|
-
]
|
|
438
|
-
}).then(({ x, y }) => {
|
|
439
|
-
Object.assign(popup.style, {
|
|
440
|
-
left: `${x}px`,
|
|
441
|
-
top: `${y}px`
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
};
|
|
445
|
-
updatePosition();
|
|
446
|
-
this.#cleanup = autoUpdate(trigger, popup, updatePosition);
|
|
447
|
-
}
|
|
448
|
-
#clearHoverTimeout() {
|
|
449
|
-
if (this.#hoverTimeout) {
|
|
450
|
-
clearTimeout(this.#hoverTimeout);
|
|
451
|
-
this.#hoverTimeout = null;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
#handleMouseEnter() {
|
|
455
|
-
if (!this.openOnHover) return;
|
|
456
|
-
this.#clearHoverTimeout();
|
|
457
|
-
this.#hoverTimeout = globalThis.setTimeout(() => {
|
|
458
|
-
this.setOpen(true);
|
|
459
|
-
}, this.delay);
|
|
460
|
-
}
|
|
461
|
-
#handleMouseLeave(event) {
|
|
462
|
-
if (!this.openOnHover) return;
|
|
463
|
-
if (event.relatedTarget && this.#popupElement?.contains(event.relatedTarget)) return;
|
|
464
|
-
this.#clearHoverTimeout();
|
|
465
|
-
this.#hoverTimeout = globalThis.setTimeout(() => {
|
|
466
|
-
this.setOpen(false);
|
|
467
|
-
}, this.closeDelay);
|
|
468
|
-
}
|
|
469
|
-
#handleFocusIn(_event) {
|
|
470
|
-
this.setOpen(true);
|
|
471
|
-
}
|
|
472
|
-
#handleFocusOut(event) {
|
|
473
|
-
const relatedTarget = event.relatedTarget;
|
|
474
|
-
if (relatedTarget && relatedTarget.hasAttribute("data-focus-guard")) return;
|
|
475
|
-
this.setOpen(false);
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
var MediaPopoverTrigger = class extends HTMLElement {
|
|
479
|
-
connectedCallback() {
|
|
480
|
-
this.style.display = "contents";
|
|
481
|
-
const triggerElement = this.firstElementChild;
|
|
482
|
-
if (triggerElement) {
|
|
483
|
-
triggerElement.setAttribute("aria-haspopup", "true");
|
|
484
|
-
triggerElement.setAttribute("aria-expanded", "false");
|
|
485
|
-
new MutationObserver((mutations) => {
|
|
486
|
-
mutations.forEach((mutation) => {
|
|
487
|
-
if (mutation.type === "attributes") {
|
|
488
|
-
const rootElement = this.closest("media-popover-root");
|
|
489
|
-
let popupElement = rootElement.querySelector("media-popover-popup");
|
|
490
|
-
if (!popupElement) {
|
|
491
|
-
const portalElement = rootElement.querySelector("media-popover-portal");
|
|
492
|
-
if (!portalElement) return;
|
|
493
|
-
popupElement = portalElement.querySelector("media-popover-popup");
|
|
494
|
-
if (!popupElement) return;
|
|
495
|
-
}
|
|
496
|
-
const attributeName = mutation.attributeName;
|
|
497
|
-
if (!attributeName || !attributeName.startsWith("data-")) return;
|
|
498
|
-
const attributeValue = triggerElement.getAttribute(attributeName);
|
|
499
|
-
if (attributeValue !== null) popupElement.setAttribute(attributeName, attributeValue);
|
|
500
|
-
else popupElement.removeAttribute(attributeName);
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
}).observe(triggerElement, { attributes: true });
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
};
|
|
507
|
-
var MediaPopoverPortal = class extends HTMLElement {
|
|
508
|
-
#portal = null;
|
|
509
|
-
#childrenArray = [];
|
|
510
|
-
#guards = [];
|
|
511
|
-
connectedCallback() {
|
|
512
|
-
this.style.display = "contents";
|
|
513
|
-
this.#setupPortal();
|
|
514
|
-
}
|
|
515
|
-
disconnectedCallback() {
|
|
516
|
-
this.#cleanupPortal();
|
|
517
|
-
}
|
|
518
|
-
querySelector(selector) {
|
|
519
|
-
return this.#portal.querySelector(selector);
|
|
520
|
-
}
|
|
521
|
-
querySelectorAll(selector) {
|
|
522
|
-
return this.#portal.querySelectorAll(selector);
|
|
523
|
-
}
|
|
524
|
-
handleEvent(event) {
|
|
525
|
-
this.dispatchEvent(new Event(event.type, { bubbles: true }));
|
|
526
|
-
}
|
|
527
|
-
#setupPortal() {
|
|
528
|
-
const portalId = this.getAttribute("root-id") ?? "@default_portal_id";
|
|
529
|
-
if (!portalId) return;
|
|
530
|
-
const portalContainer = this.getRootNode().getElementById(portalId) ?? this.getRootNode().querySelector("media-container")?.shadowRoot?.getElementById(portalId) ? this.getRootNode().querySelector("media-container") : void 0;
|
|
531
|
-
if (!portalContainer) return;
|
|
532
|
-
this.#portal = document.createElement("div");
|
|
533
|
-
this.#portal.slot = "portal";
|
|
534
|
-
this.#portal.id = uniqueId();
|
|
535
|
-
this.#childrenArray = Array.from(this.children);
|
|
536
|
-
this.#portal.append(...this.#childrenArray);
|
|
537
|
-
portalContainer.append(this.#portal);
|
|
538
|
-
}
|
|
539
|
-
#cleanupPortal() {
|
|
540
|
-
if (!this.#portal) return;
|
|
541
|
-
this.removeGuards();
|
|
542
|
-
this.append(...this.#childrenArray);
|
|
543
|
-
this.#portal.remove();
|
|
544
|
-
this.#portal = null;
|
|
545
|
-
this.#childrenArray = [];
|
|
546
|
-
}
|
|
547
|
-
renderGuards() {
|
|
548
|
-
if (!this.#portal) return;
|
|
549
|
-
if (this.#guards.length === 0) {
|
|
550
|
-
const beforeInsideGuard = createFocusGuard("inside");
|
|
551
|
-
const afterInsideGuard = createFocusGuard("inside");
|
|
552
|
-
const beforeOutsideGuard = createFocusGuard("outside");
|
|
553
|
-
const afterOutsideGuard = createFocusGuard("outside");
|
|
554
|
-
beforeOutsideGuard.addEventListener("focus", (event) => {
|
|
555
|
-
if (this.#portal && isOutsideEvent(event, this.#portal)) beforeInsideGuard.focus();
|
|
556
|
-
else getPreviousTabbable(this)?.focus();
|
|
557
|
-
});
|
|
558
|
-
afterOutsideGuard.addEventListener("focus", (event) => {
|
|
559
|
-
if (this.#portal && isOutsideEvent(event, this.#portal)) afterInsideGuard.focus();
|
|
560
|
-
else getNextTabbable(this)?.focus();
|
|
561
|
-
});
|
|
562
|
-
beforeInsideGuard.addEventListener("focus", (event) => {
|
|
563
|
-
if (this.#portal && isOutsideEvent(event, this.#portal)) getNextTabbable(this.#portal)?.focus();
|
|
564
|
-
else beforeOutsideGuard.focus();
|
|
565
|
-
});
|
|
566
|
-
afterInsideGuard.addEventListener("focus", (event) => {
|
|
567
|
-
if (this.#portal && isOutsideEvent(event, this.#portal)) getPreviousTabbable(this.#portal)?.focus();
|
|
568
|
-
else afterOutsideGuard.focus();
|
|
569
|
-
});
|
|
570
|
-
this.prepend(beforeOutsideGuard);
|
|
571
|
-
this.append(afterOutsideGuard);
|
|
572
|
-
this.#portal.prepend(beforeInsideGuard);
|
|
573
|
-
this.#portal.append(afterInsideGuard);
|
|
574
|
-
this.#guards = [
|
|
575
|
-
beforeOutsideGuard,
|
|
576
|
-
afterOutsideGuard,
|
|
577
|
-
beforeInsideGuard,
|
|
578
|
-
afterInsideGuard
|
|
579
|
-
];
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
removeGuards() {
|
|
583
|
-
this.#guards.forEach((guard) => guard.remove());
|
|
584
|
-
this.#guards = [];
|
|
585
|
-
}
|
|
586
|
-
};
|
|
587
|
-
function createFocusGuard(dataType) {
|
|
588
|
-
const focusGuard = document.createElement("span");
|
|
589
|
-
focusGuard.setAttribute("data-type", dataType);
|
|
590
|
-
focusGuard.setAttribute("tabindex", "0");
|
|
591
|
-
focusGuard.toggleAttribute("data-focus-guard", true);
|
|
592
|
-
return focusGuard;
|
|
593
|
-
}
|
|
594
|
-
var MediaPopoverPositioner = class extends HTMLElement {
|
|
595
|
-
connectedCallback() {
|
|
596
|
-
this.style.display = "contents";
|
|
597
|
-
const popup = this.firstElementChild;
|
|
598
|
-
if (popup) Object.assign(popup.style, {
|
|
599
|
-
position: "absolute",
|
|
600
|
-
top: "0",
|
|
601
|
-
left: "0"
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
get side() {
|
|
605
|
-
return this.getAttribute("side");
|
|
606
|
-
}
|
|
607
|
-
get sideOffset() {
|
|
608
|
-
return Number.parseInt(this.getAttribute("side-offset") ?? "0", 10);
|
|
609
|
-
}
|
|
610
|
-
};
|
|
611
|
-
var MediaPopoverPopup = class extends HTMLElement {
|
|
612
|
-
connectedCallback() {
|
|
613
|
-
this.setAttribute("role", "dialog");
|
|
614
|
-
this.setAttribute("aria-modal", "false");
|
|
615
|
-
this.id = uniqueId();
|
|
616
|
-
}
|
|
617
|
-
};
|
|
618
|
-
if (!globalThis.customElements.get("media-popover-root")) globalThis.customElements.define("media-popover-root", MediaPopoverRoot);
|
|
619
|
-
if (!globalThis.customElements.get("media-popover-trigger")) globalThis.customElements.define("media-popover-trigger", MediaPopoverTrigger);
|
|
620
|
-
if (!globalThis.customElements.get("media-popover-portal")) globalThis.customElements.define("media-popover-portal", MediaPopoverPortal);
|
|
621
|
-
if (!globalThis.customElements.get("media-popover-positioner")) globalThis.customElements.define("media-popover-positioner", MediaPopoverPositioner);
|
|
622
|
-
if (!globalThis.customElements.get("media-popover-popup")) globalThis.customElements.define("media-popover-popup", MediaPopoverPopup);
|
|
623
|
-
const Popover = {
|
|
624
|
-
Root: MediaPopoverRoot,
|
|
625
|
-
Trigger: MediaPopoverTrigger,
|
|
626
|
-
Portal: MediaPopoverPortal,
|
|
627
|
-
Positioner: MediaPopoverPositioner,
|
|
628
|
-
Popup: MediaPopoverPopup
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
//#endregion
|
|
632
|
-
//#region src/components/media-time-slider.ts
|
|
633
|
-
/**
|
|
634
|
-
* TimeSlider Root props hook - equivalent to React's useTimeSliderRootProps
|
|
635
|
-
* Handles element attributes and properties based on state
|
|
636
|
-
*/
|
|
637
|
-
const getTimeSliderRootProps = (state, element) => {
|
|
638
|
-
const formatTime = (time) => {
|
|
639
|
-
return `${Math.floor(time / 60)}:${Math.floor(time % 60).toString().padStart(2, "0")}`;
|
|
640
|
-
};
|
|
641
|
-
const currentTimeText = formatTime(state.currentTime);
|
|
642
|
-
const durationText = formatTime(state.duration);
|
|
643
|
-
return {
|
|
644
|
-
role: "slider",
|
|
645
|
-
tabindex: element.getAttribute("tabindex") ?? "0",
|
|
646
|
-
"data-current-time": state.currentTime.toString(),
|
|
647
|
-
"data-duration": state.duration.toString(),
|
|
648
|
-
"data-orientation": element.orientation || "horizontal",
|
|
649
|
-
"aria-label": "Seek",
|
|
650
|
-
"aria-valuemin": "0",
|
|
651
|
-
"aria-valuemax": Math.round(state.duration).toString(),
|
|
652
|
-
"aria-valuenow": Math.round(state.currentTime).toString(),
|
|
653
|
-
"aria-valuetext": `${currentTimeText} of ${durationText}`,
|
|
654
|
-
"aria-orientation": element.orientation || "horizontal"
|
|
655
|
-
};
|
|
656
|
-
};
|
|
657
|
-
var TimeSliderRootBase = class extends HTMLElement {
|
|
658
|
-
constructor(..._args) {
|
|
659
|
-
super(..._args);
|
|
660
|
-
this._core = null;
|
|
661
|
-
}
|
|
662
|
-
static {
|
|
663
|
-
this.observedAttributes = ["orientation"];
|
|
664
|
-
}
|
|
665
|
-
get currentTime() {
|
|
666
|
-
return this._state?.currentTime ?? 0;
|
|
667
|
-
}
|
|
668
|
-
get duration() {
|
|
669
|
-
return this._state?.duration ?? 0;
|
|
670
|
-
}
|
|
671
|
-
get orientation() {
|
|
672
|
-
return this.getAttribute("orientation") || "horizontal";
|
|
673
|
-
}
|
|
674
|
-
attributeChangedCallback(name, _oldValue, _newValue) {
|
|
675
|
-
if (name === "orientation" && this._state) this._render(getTimeSliderRootProps(this._state, this), this._state);
|
|
676
|
-
}
|
|
677
|
-
_update(_props, state) {
|
|
678
|
-
this._state = state;
|
|
679
|
-
if (state && !this._core) {
|
|
680
|
-
this._core = new TimeSlider();
|
|
681
|
-
this._core.subscribe(() => this._render(getTimeSliderRootProps(state, this), state));
|
|
682
|
-
this._core.attach(this);
|
|
683
|
-
state.core = this._core;
|
|
684
|
-
}
|
|
685
|
-
this._core?.setState(state);
|
|
686
|
-
}
|
|
687
|
-
_render(props, state) {
|
|
688
|
-
const coreState = state?.core?.getState();
|
|
689
|
-
if (!coreState) return;
|
|
690
|
-
this.style.setProperty("--slider-fill", `${Math.round(coreState._fillWidth)}%`);
|
|
691
|
-
this.style.setProperty("--slider-pointer", `${Math.round(coreState._pointerWidth)}%`);
|
|
692
|
-
setAttributes(this, props);
|
|
693
|
-
}
|
|
694
|
-
};
|
|
695
|
-
var TimeSliderTrackBase = class extends HTMLElement {
|
|
696
|
-
constructor() {
|
|
697
|
-
super();
|
|
698
|
-
}
|
|
699
|
-
connectedCallback() {
|
|
700
|
-
const rootElement = this.closest("media-time-slider-root");
|
|
701
|
-
if (rootElement?._state?.core) rootElement._state.core.setState({ _trackElement: this });
|
|
702
|
-
}
|
|
703
|
-
_update(props, _state) {
|
|
704
|
-
setAttributes(this, props);
|
|
705
|
-
if (props["data-orientation"] === "horizontal") {
|
|
706
|
-
this.style.width = "100%";
|
|
707
|
-
this.style.removeProperty("height");
|
|
708
|
-
} else {
|
|
709
|
-
this.style.height = "100%";
|
|
710
|
-
this.style.removeProperty("width");
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
};
|
|
714
|
-
var TimeSliderProgressBase = class extends HTMLElement {
|
|
715
|
-
constructor() {
|
|
716
|
-
super();
|
|
717
|
-
this.style.position = "absolute";
|
|
718
|
-
this.style.width = "var(--slider-fill, 0%)";
|
|
719
|
-
this.style.height = "100%";
|
|
720
|
-
}
|
|
721
|
-
_update(props, _state) {
|
|
722
|
-
setAttributes(this, props);
|
|
723
|
-
if (props["data-orientation"] === "horizontal") {
|
|
724
|
-
this.style.width = "var(--slider-fill, 0%)";
|
|
725
|
-
this.style.height = "100%";
|
|
726
|
-
this.style.top = "0";
|
|
727
|
-
this.style.removeProperty("bottom");
|
|
728
|
-
} else {
|
|
729
|
-
this.style.height = "var(--slider-fill, 0%)";
|
|
730
|
-
this.style.width = "100%";
|
|
731
|
-
this.style.bottom = "0";
|
|
732
|
-
this.style.removeProperty("top");
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
};
|
|
736
|
-
var TimeSliderPointerBase = class extends HTMLElement {
|
|
737
|
-
constructor() {
|
|
738
|
-
super();
|
|
739
|
-
this.style.position = "absolute";
|
|
740
|
-
this.style.width = "var(--slider-pointer, 0%)";
|
|
741
|
-
this.style.height = "100%";
|
|
742
|
-
}
|
|
743
|
-
_update(props, _state) {
|
|
744
|
-
setAttributes(this, props);
|
|
745
|
-
if (props["data-orientation"] === "horizontal") {
|
|
746
|
-
this.style.width = "var(--slider-pointer, 0%)";
|
|
747
|
-
this.style.height = "100%";
|
|
748
|
-
this.style.top = "0";
|
|
749
|
-
this.style.removeProperty("bottom");
|
|
750
|
-
} else {
|
|
751
|
-
this.style.height = "var(--slider-pointer, 0%)";
|
|
752
|
-
this.style.width = "100%";
|
|
753
|
-
this.style.bottom = "0";
|
|
754
|
-
this.style.removeProperty("top");
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
var TimeSliderThumbBase = class extends HTMLElement {
|
|
759
|
-
constructor() {
|
|
760
|
-
super();
|
|
761
|
-
this.style.position = "absolute";
|
|
762
|
-
}
|
|
763
|
-
_update(props, _state) {
|
|
764
|
-
setAttributes(this, props);
|
|
765
|
-
if (props["data-orientation"] === "horizontal") {
|
|
766
|
-
this.style.left = "var(--slider-fill, 0%)";
|
|
767
|
-
this.style.top = "50%";
|
|
768
|
-
this.style.transform = "translate(-50%, -50%)";
|
|
769
|
-
} else {
|
|
770
|
-
this.style.bottom = "var(--slider-fill, 0%)";
|
|
771
|
-
this.style.left = "50%";
|
|
772
|
-
this.style.transform = "translate(-50%, 50%)";
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
};
|
|
776
|
-
const useTimeSliderRootState = {
|
|
777
|
-
keys: timeSliderStateDefinition.keys,
|
|
778
|
-
transform: (rawState, mediaStore) => ({
|
|
779
|
-
...timeSliderStateDefinition.stateTransform(rawState),
|
|
780
|
-
...timeSliderStateDefinition.createRequestMethods(mediaStore.dispatch),
|
|
781
|
-
core: null
|
|
782
|
-
})
|
|
783
|
-
};
|
|
784
|
-
const getTimeSliderTrackProps = (_state, element) => {
|
|
785
|
-
const rootElement = element.closest("media-time-slider-root");
|
|
786
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
787
|
-
};
|
|
788
|
-
const getTimeSliderProgressProps = (_state, element) => {
|
|
789
|
-
const rootElement = element.closest("media-time-slider-root");
|
|
790
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
791
|
-
};
|
|
792
|
-
const getTimeSliderPointerProps = (_state, element) => {
|
|
793
|
-
const rootElement = element.closest("media-time-slider-root");
|
|
794
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
795
|
-
};
|
|
796
|
-
const getTimeSliderThumbProps = (_state, element) => {
|
|
797
|
-
const rootElement = element.closest("media-time-slider-root");
|
|
798
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
799
|
-
};
|
|
800
|
-
const TimeSliderRoot = toConnectedHTMLComponent(TimeSliderRootBase, useTimeSliderRootState, getTimeSliderRootProps, "TimeSliderRoot");
|
|
801
|
-
const TimeSliderTrack = toConnectedHTMLComponent(TimeSliderTrackBase, {
|
|
802
|
-
keys: [],
|
|
803
|
-
transform: () => ({})
|
|
804
|
-
}, getTimeSliderTrackProps, "TimeSliderTrack");
|
|
805
|
-
const TimeSliderProgress = toConnectedHTMLComponent(TimeSliderProgressBase, {
|
|
806
|
-
keys: [],
|
|
807
|
-
transform: () => ({})
|
|
808
|
-
}, getTimeSliderProgressProps, "TimeSliderProgress");
|
|
809
|
-
const TimeSliderPointer = toConnectedHTMLComponent(TimeSliderPointerBase, {
|
|
810
|
-
keys: [],
|
|
811
|
-
transform: () => ({})
|
|
812
|
-
}, getTimeSliderPointerProps, "TimeSliderPointer");
|
|
813
|
-
const TimeSliderThumb = toConnectedHTMLComponent(TimeSliderThumbBase, {
|
|
814
|
-
keys: [],
|
|
815
|
-
transform: () => ({})
|
|
816
|
-
}, getTimeSliderThumbProps, "TimeSliderThumb");
|
|
817
|
-
const TimeSlider$1 = Object.assign({}, {
|
|
818
|
-
Root: TimeSliderRoot,
|
|
819
|
-
Track: TimeSliderTrack,
|
|
820
|
-
Progress: TimeSliderProgress,
|
|
821
|
-
Pointer: TimeSliderPointer,
|
|
822
|
-
Thumb: TimeSliderThumb
|
|
823
|
-
});
|
|
824
|
-
if (!globalThis.customElements.get("media-time-slider-root")) globalThis.customElements.define("media-time-slider-root", TimeSliderRoot);
|
|
825
|
-
if (!globalThis.customElements.get("media-time-slider-track")) globalThis.customElements.define("media-time-slider-track", TimeSliderTrack);
|
|
826
|
-
if (!globalThis.customElements.get("media-time-slider-progress")) globalThis.customElements.define("media-time-slider-progress", TimeSliderProgress);
|
|
827
|
-
if (!globalThis.customElements.get("media-time-slider-pointer")) globalThis.customElements.define("media-time-slider-pointer", TimeSliderPointer);
|
|
828
|
-
if (!globalThis.customElements.get("media-time-slider-thumb")) globalThis.customElements.define("media-time-slider-thumb", TimeSliderThumb);
|
|
829
|
-
|
|
830
|
-
//#endregion
|
|
831
|
-
//#region src/components/media-tooltip.ts
|
|
832
|
-
var MediaTooltipRoot = class extends HTMLElement {
|
|
833
|
-
#open = false;
|
|
834
|
-
#hoverTimeout = null;
|
|
835
|
-
#cleanup = null;
|
|
836
|
-
#arrowElement = null;
|
|
837
|
-
#mousePosition = {
|
|
838
|
-
x: 0,
|
|
839
|
-
y: 0
|
|
840
|
-
};
|
|
841
|
-
#transitionStatus = "initial";
|
|
842
|
-
constructor() {
|
|
843
|
-
super();
|
|
844
|
-
this.addEventListener("mouseenter", this);
|
|
845
|
-
this.addEventListener("mouseleave", this);
|
|
846
|
-
this.addEventListener("mousemove", this);
|
|
847
|
-
}
|
|
848
|
-
handleEvent(event) {
|
|
849
|
-
if (event.type === "mouseenter") this.#handleMouseEnter();
|
|
850
|
-
else if (event.type === "mouseleave") this.#handleMouseLeave();
|
|
851
|
-
else if (event.type === "mousemove") this.#handleMouseMove(event);
|
|
852
|
-
}
|
|
853
|
-
connectedCallback() {
|
|
854
|
-
this.#updateVisibility();
|
|
855
|
-
}
|
|
856
|
-
disconnectedCallback() {
|
|
857
|
-
this.#clearHoverTimeout();
|
|
858
|
-
this.#cleanup?.();
|
|
859
|
-
this.#transitionStatus = "unmounted";
|
|
860
|
-
this.#updateVisibility();
|
|
861
|
-
}
|
|
862
|
-
static get observedAttributes() {
|
|
863
|
-
return [
|
|
864
|
-
"delay",
|
|
865
|
-
"close-delay",
|
|
866
|
-
"track-cursor-axis"
|
|
867
|
-
];
|
|
868
|
-
}
|
|
869
|
-
get delay() {
|
|
870
|
-
return Number.parseInt(this.getAttribute("delay") ?? "0", 10);
|
|
871
|
-
}
|
|
872
|
-
get closeDelay() {
|
|
873
|
-
return Number.parseInt(this.getAttribute("close-delay") ?? "0", 10);
|
|
874
|
-
}
|
|
875
|
-
get trackCursorAxis() {
|
|
876
|
-
const value = this.getAttribute("track-cursor-axis");
|
|
877
|
-
return value === "x" || value === "y" || value === "both" ? value : void 0;
|
|
878
|
-
}
|
|
879
|
-
get #triggerElement() {
|
|
880
|
-
return this.querySelector("media-tooltip-trigger");
|
|
881
|
-
}
|
|
882
|
-
get #portalElement() {
|
|
883
|
-
return this.querySelector("media-tooltip-portal");
|
|
884
|
-
}
|
|
885
|
-
get #positionerElement() {
|
|
886
|
-
return this.#portalElement?.querySelector("media-tooltip-positioner");
|
|
887
|
-
}
|
|
888
|
-
get #popupElement() {
|
|
889
|
-
return this.#portalElement?.querySelector("media-tooltip-popup");
|
|
890
|
-
}
|
|
891
|
-
#setOpen(open) {
|
|
892
|
-
if (this.#open === open) return;
|
|
893
|
-
this.#open = open;
|
|
894
|
-
if (open) {
|
|
895
|
-
this.#transitionStatus = "initial";
|
|
896
|
-
requestAnimationFrame(() => {
|
|
897
|
-
this.#transitionStatus = "open";
|
|
898
|
-
this.#updateVisibility();
|
|
899
|
-
});
|
|
900
|
-
} else this.#transitionStatus = "close";
|
|
901
|
-
this.#updateVisibility();
|
|
902
|
-
if (open) this.#setupFloating();
|
|
903
|
-
else {
|
|
904
|
-
this.#cleanup?.();
|
|
905
|
-
this.#cleanup = null;
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
#updateVisibility() {
|
|
909
|
-
this.style.display = "contents";
|
|
910
|
-
if (this.#popupElement) {
|
|
911
|
-
const placement = this.#positionerElement?.side ?? "top";
|
|
912
|
-
this.#popupElement.setAttribute("data-side", placement);
|
|
913
|
-
this.#popupElement.toggleAttribute("data-starting-style", this.#transitionStatus === "initial");
|
|
914
|
-
this.#popupElement.toggleAttribute("data-open", this.#transitionStatus === "initial" || this.#transitionStatus === "open");
|
|
915
|
-
this.#popupElement.toggleAttribute("data-ending-style", this.#transitionStatus === "close" || this.#transitionStatus === "unmounted");
|
|
916
|
-
this.#popupElement.toggleAttribute("data-closed", this.#transitionStatus === "close" || this.#transitionStatus === "unmounted");
|
|
917
|
-
}
|
|
918
|
-
const triggerElement = this.#triggerElement?.firstElementChild;
|
|
919
|
-
if (triggerElement) triggerElement.toggleAttribute("data-popup-open", this.#open);
|
|
920
|
-
}
|
|
921
|
-
#setupFloating() {
|
|
922
|
-
if (!this.#triggerElement || !this.#popupElement) return;
|
|
923
|
-
const trigger = this.#triggerElement.firstElementChild;
|
|
924
|
-
const popup = this.#popupElement;
|
|
925
|
-
if (!trigger || !popup) return;
|
|
926
|
-
const placement = this.#positionerElement?.side ?? "top";
|
|
927
|
-
const sideOffset = this.#positionerElement?.sideOffset ?? 0;
|
|
928
|
-
const collisionPadding = this.#positionerElement?.collisionPadding ?? 0;
|
|
929
|
-
const mediaContainer = this.closest("media-container");
|
|
930
|
-
this.#arrowElement = popup.querySelector("media-tooltip-arrow");
|
|
931
|
-
const updatePosition = () => {
|
|
932
|
-
const middleware = [
|
|
933
|
-
offset(sideOffset),
|
|
934
|
-
flip(),
|
|
935
|
-
shift({
|
|
936
|
-
boundary: mediaContainer,
|
|
937
|
-
padding: collisionPadding
|
|
938
|
-
})
|
|
939
|
-
];
|
|
940
|
-
if (this.#arrowElement) middleware.push(arrow({ element: this.#arrowElement }));
|
|
941
|
-
computePosition(this.trackCursorAxis ? { getBoundingClientRect: () => {
|
|
942
|
-
const triggerRect = trigger.getBoundingClientRect();
|
|
943
|
-
if (this.trackCursorAxis === "x") return {
|
|
944
|
-
width: 0,
|
|
945
|
-
height: 0,
|
|
946
|
-
top: triggerRect.top,
|
|
947
|
-
right: this.#mousePosition.x,
|
|
948
|
-
bottom: triggerRect.bottom,
|
|
949
|
-
left: this.#mousePosition.x,
|
|
950
|
-
x: this.#mousePosition.x,
|
|
951
|
-
y: triggerRect.top
|
|
952
|
-
};
|
|
953
|
-
else if (this.trackCursorAxis === "y") return {
|
|
954
|
-
width: 0,
|
|
955
|
-
height: 0,
|
|
956
|
-
top: this.#mousePosition.y,
|
|
957
|
-
right: triggerRect.right,
|
|
958
|
-
bottom: this.#mousePosition.y,
|
|
959
|
-
left: triggerRect.left,
|
|
960
|
-
x: triggerRect.left,
|
|
961
|
-
y: this.#mousePosition.y
|
|
962
|
-
};
|
|
963
|
-
else return {
|
|
964
|
-
width: 0,
|
|
965
|
-
height: 0,
|
|
966
|
-
top: this.#mousePosition.y,
|
|
967
|
-
right: this.#mousePosition.x,
|
|
968
|
-
bottom: this.#mousePosition.y,
|
|
969
|
-
left: this.#mousePosition.x,
|
|
970
|
-
x: this.#mousePosition.x,
|
|
971
|
-
y: this.#mousePosition.y
|
|
972
|
-
};
|
|
973
|
-
} } : trigger, popup, {
|
|
974
|
-
placement,
|
|
975
|
-
middleware
|
|
976
|
-
}).then(({ x, y, middlewareData, placement: computedPlacement }) => {
|
|
977
|
-
Object.assign(popup.style, {
|
|
978
|
-
left: `${x}px`,
|
|
979
|
-
top: `${y}px`
|
|
980
|
-
});
|
|
981
|
-
popup.setAttribute("data-side", computedPlacement);
|
|
982
|
-
if (this.#arrowElement && middlewareData.arrow) {
|
|
983
|
-
const { x: arrowX, y: arrowY } = middlewareData.arrow;
|
|
984
|
-
Object.assign(this.#arrowElement.style, {
|
|
985
|
-
left: arrowX != null ? `${arrowX}px` : void 0,
|
|
986
|
-
top: arrowY != null ? `${arrowY}px` : void 0
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
});
|
|
990
|
-
};
|
|
991
|
-
updatePosition();
|
|
992
|
-
if (!this.trackCursorAxis) this.#cleanup = autoUpdate(trigger, popup, updatePosition);
|
|
993
|
-
}
|
|
994
|
-
#updatePosition() {
|
|
995
|
-
if (this.#open && this.trackCursorAxis) this.#setupFloating();
|
|
996
|
-
}
|
|
997
|
-
#clearHoverTimeout() {
|
|
998
|
-
if (this.#hoverTimeout) {
|
|
999
|
-
clearTimeout(this.#hoverTimeout);
|
|
1000
|
-
this.#hoverTimeout = null;
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
#handleMouseEnter() {
|
|
1004
|
-
this.#clearHoverTimeout();
|
|
1005
|
-
this.#hoverTimeout = globalThis.setTimeout(() => {
|
|
1006
|
-
this.#setOpen(true);
|
|
1007
|
-
}, this.delay);
|
|
1008
|
-
}
|
|
1009
|
-
#handleMouseLeave() {
|
|
1010
|
-
this.#clearHoverTimeout();
|
|
1011
|
-
this.#hoverTimeout = globalThis.setTimeout(() => {
|
|
1012
|
-
this.#setOpen(false);
|
|
1013
|
-
}, this.closeDelay);
|
|
1014
|
-
}
|
|
1015
|
-
#handleMouseMove(event) {
|
|
1016
|
-
if (this.trackCursorAxis) {
|
|
1017
|
-
this.#mousePosition = {
|
|
1018
|
-
x: event.clientX,
|
|
1019
|
-
y: event.clientY
|
|
1020
|
-
};
|
|
1021
|
-
if (this.#open) this.#updatePosition();
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
};
|
|
1025
|
-
var MediaTooltipTrigger = class extends HTMLElement {
|
|
1026
|
-
connectedCallback() {
|
|
1027
|
-
this.style.display = "contents";
|
|
1028
|
-
const triggerElement = this.firstElementChild;
|
|
1029
|
-
if (triggerElement) new MutationObserver((mutations) => {
|
|
1030
|
-
mutations.forEach((mutation) => {
|
|
1031
|
-
if (mutation.type === "attributes") {
|
|
1032
|
-
const rootElement = this.closest("media-tooltip-root");
|
|
1033
|
-
let popupElement = rootElement.querySelector("media-tooltip-popup");
|
|
1034
|
-
if (!popupElement) {
|
|
1035
|
-
const portalElement = rootElement.querySelector("media-tooltip-portal");
|
|
1036
|
-
if (!portalElement) return;
|
|
1037
|
-
popupElement = portalElement.querySelector("media-tooltip-popup");
|
|
1038
|
-
if (!popupElement) return;
|
|
1039
|
-
}
|
|
1040
|
-
const attributeName = mutation.attributeName;
|
|
1041
|
-
if (!attributeName || !attributeName.startsWith("data-")) return;
|
|
1042
|
-
const attributeValue = triggerElement.getAttribute(attributeName);
|
|
1043
|
-
if (attributeValue !== null) popupElement.setAttribute(attributeName, attributeValue);
|
|
1044
|
-
else popupElement.removeAttribute(attributeName);
|
|
1045
|
-
}
|
|
1046
|
-
});
|
|
1047
|
-
}).observe(triggerElement, { attributes: true });
|
|
1048
|
-
}
|
|
1049
|
-
};
|
|
1050
|
-
var MediaTooltipPortal = class extends HTMLElement {
|
|
1051
|
-
#portal = null;
|
|
1052
|
-
connectedCallback() {
|
|
1053
|
-
this.style.display = "contents";
|
|
1054
|
-
this.#setupPortal();
|
|
1055
|
-
}
|
|
1056
|
-
disconnectedCallback() {
|
|
1057
|
-
this.#cleanupPortal();
|
|
1058
|
-
}
|
|
1059
|
-
querySelector(selector) {
|
|
1060
|
-
return this.#portal?.querySelector(selector) ?? null;
|
|
1061
|
-
}
|
|
1062
|
-
#setupPortal() {
|
|
1063
|
-
const portalId = this.getAttribute("root-id") ?? "@default_portal_id";
|
|
1064
|
-
if (!portalId) return;
|
|
1065
|
-
const portalContainer = this.getRootNode().getElementById(portalId) ?? this.getRootNode().querySelector("media-container")?.shadowRoot?.getElementById(portalId) ? this.getRootNode().querySelector("media-container") : void 0;
|
|
1066
|
-
if (!portalContainer) return;
|
|
1067
|
-
this.#portal = document.createElement("div");
|
|
1068
|
-
this.#portal.slot = "portal";
|
|
1069
|
-
this.#portal.id = uniqueId();
|
|
1070
|
-
portalContainer.append(this.#portal);
|
|
1071
|
-
this.#portal.append(...this.children);
|
|
1072
|
-
}
|
|
1073
|
-
#cleanupPortal() {
|
|
1074
|
-
if (!this.#portal) return;
|
|
1075
|
-
this.append(...this.#portal.children);
|
|
1076
|
-
this.#portal.remove();
|
|
1077
|
-
this.#portal = null;
|
|
1078
|
-
}
|
|
1079
|
-
};
|
|
1080
|
-
var MediaTooltipPositioner = class extends HTMLElement {
|
|
1081
|
-
connectedCallback() {
|
|
1082
|
-
this.style.display = "contents";
|
|
1083
|
-
const popup = this.firstElementChild;
|
|
1084
|
-
if (popup) Object.assign(popup.style, {
|
|
1085
|
-
position: "absolute",
|
|
1086
|
-
top: "0",
|
|
1087
|
-
left: "0"
|
|
1088
|
-
});
|
|
1089
|
-
}
|
|
1090
|
-
get side() {
|
|
1091
|
-
return this.getAttribute("side") ?? "top";
|
|
1092
|
-
}
|
|
1093
|
-
get sideOffset() {
|
|
1094
|
-
return Number.parseInt(this.getAttribute("side-offset") ?? "0", 10);
|
|
1095
|
-
}
|
|
1096
|
-
get collisionPadding() {
|
|
1097
|
-
return Number.parseInt(this.getAttribute("collision-padding") ?? "0", 10);
|
|
1098
|
-
}
|
|
1099
|
-
};
|
|
1100
|
-
var MediaTooltipPopup = class extends HTMLElement {
|
|
1101
|
-
connectedCallback() {
|
|
1102
|
-
this.setAttribute("role", "tooltip");
|
|
1103
|
-
}
|
|
1104
|
-
};
|
|
1105
|
-
var MediaTooltipArrow = class extends HTMLElement {
|
|
1106
|
-
connectedCallback() {
|
|
1107
|
-
this.setAttribute("aria-hidden", "true");
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1110
|
-
if (!globalThis.customElements.get("media-tooltip-root")) globalThis.customElements.define("media-tooltip-root", MediaTooltipRoot);
|
|
1111
|
-
if (!globalThis.customElements.get("media-tooltip-trigger")) globalThis.customElements.define("media-tooltip-trigger", MediaTooltipTrigger);
|
|
1112
|
-
if (!globalThis.customElements.get("media-tooltip-portal")) globalThis.customElements.define("media-tooltip-portal", MediaTooltipPortal);
|
|
1113
|
-
if (!globalThis.customElements.get("media-tooltip-positioner")) globalThis.customElements.define("media-tooltip-positioner", MediaTooltipPositioner);
|
|
1114
|
-
if (!globalThis.customElements.get("media-tooltip-popup")) globalThis.customElements.define("media-tooltip-popup", MediaTooltipPopup);
|
|
1115
|
-
if (!globalThis.customElements.get("media-tooltip-arrow")) globalThis.customElements.define("media-tooltip-arrow", MediaTooltipArrow);
|
|
1116
|
-
const Tooltip = {
|
|
1117
|
-
Root: MediaTooltipRoot,
|
|
1118
|
-
Trigger: MediaTooltipTrigger,
|
|
1119
|
-
Portal: MediaTooltipPortal,
|
|
1120
|
-
Positioner: MediaTooltipPositioner,
|
|
1121
|
-
Popup: MediaTooltipPopup,
|
|
1122
|
-
Arrow: MediaTooltipArrow
|
|
1123
|
-
};
|
|
1124
|
-
|
|
1125
|
-
//#endregion
|
|
1126
|
-
//#region src/components/media-volume-slider.ts
|
|
1127
|
-
/**
|
|
1128
|
-
* VolumeSlider Root props hook - equivalent to React's useVolumeSliderRootProps
|
|
1129
|
-
* Handles element attributes and properties based on state
|
|
1130
|
-
*/
|
|
1131
|
-
const getVolumeSliderRootProps = (state, element) => {
|
|
1132
|
-
const volumeText = `${Math.round(state.muted ? 0 : state.volume * 100)}%`;
|
|
1133
|
-
return {
|
|
1134
|
-
role: "slider",
|
|
1135
|
-
tabindex: element.getAttribute("tabindex") ?? "0",
|
|
1136
|
-
"data-muted": state.muted.toString(),
|
|
1137
|
-
"data-volume-level": state.volumeLevel,
|
|
1138
|
-
"data-orientation": element.orientation || "horizontal",
|
|
1139
|
-
"aria-label": "Volume",
|
|
1140
|
-
"aria-valuemin": "0",
|
|
1141
|
-
"aria-valuemax": "100",
|
|
1142
|
-
"aria-valuetext": volumeText,
|
|
1143
|
-
"aria-orientation": element.orientation || "horizontal"
|
|
1144
|
-
};
|
|
1145
|
-
};
|
|
1146
|
-
var VolumeSliderRootBase = class extends HTMLElement {
|
|
1147
|
-
constructor(..._args) {
|
|
1148
|
-
super(..._args);
|
|
1149
|
-
this._core = null;
|
|
1150
|
-
}
|
|
1151
|
-
static {
|
|
1152
|
-
this.observedAttributes = ["orientation"];
|
|
1153
|
-
}
|
|
1154
|
-
get volume() {
|
|
1155
|
-
return this._state?.volume;
|
|
1156
|
-
}
|
|
1157
|
-
get muted() {
|
|
1158
|
-
return this._state?.muted ?? false;
|
|
1159
|
-
}
|
|
1160
|
-
get volumeLevel() {
|
|
1161
|
-
return this._state?.volumeLevel ?? "high";
|
|
1162
|
-
}
|
|
1163
|
-
get orientation() {
|
|
1164
|
-
return this.getAttribute("orientation") || "horizontal";
|
|
1165
|
-
}
|
|
1166
|
-
attributeChangedCallback(name, _oldValue, _newValue) {
|
|
1167
|
-
if (name === "orientation" && this._state) this._render(getVolumeSliderRootProps(this._state, this), this._state);
|
|
1168
|
-
}
|
|
1169
|
-
_update(_props, state) {
|
|
1170
|
-
this._state = state;
|
|
1171
|
-
if (state && !this._core) {
|
|
1172
|
-
this._core = new VolumeSlider();
|
|
1173
|
-
this._core.subscribe(() => this._render(getVolumeSliderRootProps(state, this), state));
|
|
1174
|
-
this._core.attach(this);
|
|
1175
|
-
state.core = this._core;
|
|
1176
|
-
}
|
|
1177
|
-
this._core?.setState(state);
|
|
1178
|
-
}
|
|
1179
|
-
_render(props, state) {
|
|
1180
|
-
const coreState = state?.core?.getState();
|
|
1181
|
-
if (!coreState) return;
|
|
1182
|
-
this.style.setProperty("--slider-fill", `${coreState._fillWidth.toFixed(3)}%`);
|
|
1183
|
-
this.style.setProperty("--slider-pointer", `${coreState._pointerWidth.toFixed(3)}%`);
|
|
1184
|
-
props["aria-valuenow"] = coreState._fillWidth.toString();
|
|
1185
|
-
setAttributes(this, props);
|
|
1186
|
-
}
|
|
1187
|
-
};
|
|
1188
|
-
/**
|
|
1189
|
-
* VolumeSlider Track component - Track element that captures pointer events
|
|
1190
|
-
*/
|
|
1191
|
-
var VolumeSliderTrackBase = class extends HTMLElement {
|
|
1192
|
-
constructor() {
|
|
1193
|
-
super();
|
|
1194
|
-
}
|
|
1195
|
-
connectedCallback() {
|
|
1196
|
-
const rootElement = this.closest("media-volume-slider-root");
|
|
1197
|
-
if (rootElement?._state?.core) rootElement._state.core.setState({ _trackElement: this });
|
|
1198
|
-
}
|
|
1199
|
-
_update(props, _state) {
|
|
1200
|
-
setAttributes(this, props);
|
|
1201
|
-
if (props["data-orientation"] === "horizontal") {
|
|
1202
|
-
this.style.width = "100%";
|
|
1203
|
-
this.style.removeProperty("height");
|
|
1204
|
-
} else {
|
|
1205
|
-
this.style.height = "100%";
|
|
1206
|
-
this.style.removeProperty("width");
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
};
|
|
1210
|
-
/**
|
|
1211
|
-
* VolumeSlider Progress component - Shows current progress
|
|
1212
|
-
*/
|
|
1213
|
-
var VolumeSliderProgressBase = class extends HTMLElement {
|
|
1214
|
-
constructor() {
|
|
1215
|
-
super();
|
|
1216
|
-
this.style.position = "absolute";
|
|
1217
|
-
this.style.width = "var(--slider-fill, 0%)";
|
|
1218
|
-
this.style.height = "100%";
|
|
1219
|
-
}
|
|
1220
|
-
_update(props, _state) {
|
|
1221
|
-
setAttributes(this, props);
|
|
1222
|
-
if (props["data-orientation"] === "horizontal") {
|
|
1223
|
-
this.style.width = "var(--slider-fill, 0%)";
|
|
1224
|
-
this.style.height = "100%";
|
|
1225
|
-
this.style.top = "0";
|
|
1226
|
-
this.style.removeProperty("bottom");
|
|
1227
|
-
} else {
|
|
1228
|
-
this.style.height = "var(--slider-fill, 0%)";
|
|
1229
|
-
this.style.width = "100%";
|
|
1230
|
-
this.style.bottom = "0";
|
|
1231
|
-
this.style.removeProperty("top");
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
};
|
|
1235
|
-
/**
|
|
1236
|
-
* VolumeSlider Thumb component - Draggable thumb element
|
|
1237
|
-
*/
|
|
1238
|
-
var VolumeSliderThumbBase = class extends HTMLElement {
|
|
1239
|
-
constructor() {
|
|
1240
|
-
super();
|
|
1241
|
-
this.style.position = "absolute";
|
|
1242
|
-
}
|
|
1243
|
-
_update(props, _state) {
|
|
1244
|
-
setAttributes(this, props);
|
|
1245
|
-
if (props["data-orientation"] === "horizontal") {
|
|
1246
|
-
this.style.left = "var(--slider-fill, 0%)";
|
|
1247
|
-
this.style.top = "50%";
|
|
1248
|
-
this.style.transform = "translate(-50%, -50%)";
|
|
1249
|
-
} else {
|
|
1250
|
-
this.style.bottom = "var(--slider-fill, 0%)";
|
|
1251
|
-
this.style.left = "50%";
|
|
1252
|
-
this.style.transform = "translate(-50%, 50%)";
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
};
|
|
1256
|
-
/**
|
|
1257
|
-
* VolumeSlider Root state hook - equivalent to React's useVolumeSliderRootState
|
|
1258
|
-
* Handles media store state subscription and transformation
|
|
1259
|
-
*/
|
|
1260
|
-
const useVolumeSliderRootState = {
|
|
1261
|
-
keys: volumeSliderStateDefinition.keys,
|
|
1262
|
-
transform: (rawState, mediaStore) => ({
|
|
1263
|
-
...volumeSliderStateDefinition.stateTransform(rawState),
|
|
1264
|
-
...volumeSliderStateDefinition.createRequestMethods(mediaStore.dispatch),
|
|
1265
|
-
core: null
|
|
1266
|
-
})
|
|
1267
|
-
};
|
|
1268
|
-
/**
|
|
1269
|
-
* VolumeSlider Track props hook
|
|
1270
|
-
*/
|
|
1271
|
-
const getVolumeSliderTrackProps = (_state, element) => {
|
|
1272
|
-
const rootElement = element.closest("media-volume-slider-root");
|
|
1273
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
1274
|
-
};
|
|
1275
|
-
/**
|
|
1276
|
-
* VolumeSlider Progress props hook
|
|
1277
|
-
*/
|
|
1278
|
-
const getVolumeSliderProgressProps = (_state, element) => {
|
|
1279
|
-
const rootElement = element.closest("media-volume-slider-root");
|
|
1280
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
1281
|
-
};
|
|
1282
|
-
/**
|
|
1283
|
-
* VolumeSlider Thumb props hook
|
|
1284
|
-
*/
|
|
1285
|
-
const getVolumeSliderThumbProps = (_state, element) => {
|
|
1286
|
-
const rootElement = element.closest("media-volume-slider-root");
|
|
1287
|
-
return { "data-orientation": rootElement?.orientation || "horizontal" };
|
|
1288
|
-
};
|
|
1289
|
-
/**
|
|
1290
|
-
* Connected VolumeSlider Root component using hook-style architecture
|
|
1291
|
-
*/
|
|
1292
|
-
const VolumeSliderRoot = toConnectedHTMLComponent(VolumeSliderRootBase, useVolumeSliderRootState, getVolumeSliderRootProps, "VolumeSliderRoot");
|
|
1293
|
-
/**
|
|
1294
|
-
* Connected VolumeSlider Track component
|
|
1295
|
-
*/
|
|
1296
|
-
const VolumeSliderTrack = toConnectedHTMLComponent(VolumeSliderTrackBase, {
|
|
1297
|
-
keys: [],
|
|
1298
|
-
transform: () => ({})
|
|
1299
|
-
}, getVolumeSliderTrackProps, "VolumeSliderTrack");
|
|
1300
|
-
/**
|
|
1301
|
-
* Connected VolumeSlider Progress component
|
|
1302
|
-
*/
|
|
1303
|
-
const VolumeSliderProgress = toConnectedHTMLComponent(VolumeSliderProgressBase, {
|
|
1304
|
-
keys: [],
|
|
1305
|
-
transform: () => ({})
|
|
1306
|
-
}, getVolumeSliderProgressProps, "VolumeSliderProgress");
|
|
1307
|
-
/**
|
|
1308
|
-
* Connected VolumeSlider Thumb component
|
|
1309
|
-
*/
|
|
1310
|
-
const VolumeSliderThumb = toConnectedHTMLComponent(VolumeSliderThumbBase, {
|
|
1311
|
-
keys: [],
|
|
1312
|
-
transform: () => ({})
|
|
1313
|
-
}, getVolumeSliderThumbProps, "VolumeSliderThumb");
|
|
1314
|
-
/**
|
|
1315
|
-
* Compound VolumeSlider component object
|
|
1316
|
-
*/
|
|
1317
|
-
const VolumeSlider$1 = Object.assign({}, {
|
|
1318
|
-
Root: VolumeSliderRoot,
|
|
1319
|
-
Track: VolumeSliderTrack,
|
|
1320
|
-
Progress: VolumeSliderProgress,
|
|
1321
|
-
Thumb: VolumeSliderThumb
|
|
1322
|
-
});
|
|
1323
|
-
if (!globalThis.customElements.get("media-volume-slider-root")) globalThis.customElements.define("media-volume-slider-root", VolumeSliderRoot);
|
|
1324
|
-
if (!globalThis.customElements.get("media-volume-slider-track")) globalThis.customElements.define("media-volume-slider-track", VolumeSliderTrack);
|
|
1325
|
-
if (!globalThis.customElements.get("media-volume-slider-progress")) globalThis.customElements.define("media-volume-slider-progress", VolumeSliderProgress);
|
|
1326
|
-
if (!globalThis.customElements.get("media-volume-slider-thumb")) globalThis.customElements.define("media-volume-slider-thumb", VolumeSliderThumb);
|
|
1327
|
-
|
|
1328
|
-
//#endregion
|
|
1329
|
-
//#region src/media/media-container.ts
|
|
1330
|
-
function getTemplateHTML$1() {
|
|
1331
|
-
return `
|
|
1332
|
-
<slot name="media"></slot>
|
|
1333
|
-
<slot></slot>
|
|
1334
|
-
<div id="@default_portal_id" style={ position: absolute; zIndex: 10; }>
|
|
1335
|
-
<slot name="portal"></slot>
|
|
1336
|
-
</div>
|
|
1337
|
-
`;
|
|
1338
|
-
}
|
|
1339
|
-
const CustomElementConsumer = ConsumerMixin(HTMLElement);
|
|
1340
|
-
var MediaContainer = class extends CustomElementConsumer {
|
|
1341
|
-
static {
|
|
1342
|
-
this.shadowRootOptions = { mode: "open" };
|
|
1343
|
-
}
|
|
1344
|
-
static {
|
|
1345
|
-
this.getTemplateHTML = getTemplateHTML$1;
|
|
1346
|
-
}
|
|
1347
|
-
constructor() {
|
|
1348
|
-
super();
|
|
1349
|
-
this._paused = true;
|
|
1350
|
-
this.contexts = { mediaStore: (mediaStore) => {
|
|
1351
|
-
this._mediaStore = mediaStore;
|
|
1352
|
-
this._handleMediaSlotChange();
|
|
1353
|
-
this._registerContainerStateOwner();
|
|
1354
|
-
this._subscribeToPlayState();
|
|
1355
|
-
} };
|
|
1356
|
-
this._registerContainerStateOwner = () => {
|
|
1357
|
-
if (!this._mediaStore) return;
|
|
1358
|
-
this._mediaStore.dispatch({
|
|
1359
|
-
type: "containerstateownerchangerequest",
|
|
1360
|
-
detail: this
|
|
1361
|
-
});
|
|
1362
|
-
};
|
|
1363
|
-
this._unregisterContainerStateOwner = () => {
|
|
1364
|
-
if (!this._mediaStore) return;
|
|
1365
|
-
this._mediaStore.dispatch({
|
|
1366
|
-
type: "containerstateownerchangerequest",
|
|
1367
|
-
detail: null
|
|
1368
|
-
});
|
|
1369
|
-
};
|
|
1370
|
-
this._handleMediaSlotChange = () => {
|
|
1371
|
-
const media = this._mediaSlot.assignedElements({ flatten: true })[0];
|
|
1372
|
-
this._mediaStore.dispatch({
|
|
1373
|
-
type: "mediastateownerchangerequest",
|
|
1374
|
-
detail: media
|
|
1375
|
-
});
|
|
1376
|
-
};
|
|
1377
|
-
this._handleClick = (event) => {
|
|
1378
|
-
if (!this._mediaStore) return;
|
|
1379
|
-
if (!["video", "audio"].includes(event.target.localName || "")) return;
|
|
1380
|
-
if (this._paused) this._mediaStore.dispatch({ type: "playrequest" });
|
|
1381
|
-
else this._mediaStore.dispatch({ type: "pauserequest" });
|
|
1382
|
-
};
|
|
1383
|
-
this._subscribeToPlayState = () => {
|
|
1384
|
-
if (!this._mediaStore) return;
|
|
1385
|
-
this._mediaStore.subscribe((state) => {
|
|
1386
|
-
this._paused = state.paused ?? true;
|
|
1387
|
-
});
|
|
1388
|
-
};
|
|
1389
|
-
if (!this.shadowRoot) {
|
|
1390
|
-
this.attachShadow(this.constructor.shadowRootOptions);
|
|
1391
|
-
this.shadowRoot.innerHTML = this.constructor.getTemplateHTML();
|
|
1392
|
-
}
|
|
1393
|
-
this._mediaSlot = this.shadowRoot.querySelector("slot[name=media]");
|
|
1394
|
-
this._mediaSlot.addEventListener("slotchange", this._handleMediaSlotChange);
|
|
1395
|
-
this.addEventListener("click", this._handleClick);
|
|
1396
|
-
}
|
|
1397
|
-
connectedCallback() {
|
|
1398
|
-
super.connectedCallback?.();
|
|
1399
|
-
this._registerContainerStateOwner();
|
|
1400
|
-
}
|
|
1401
|
-
disconnectedCallback() {
|
|
1402
|
-
super.disconnectedCallback?.();
|
|
1403
|
-
this._unregisterContainerStateOwner();
|
|
1404
|
-
}
|
|
1405
|
-
};
|
|
1406
|
-
if (!globalThis.customElements.get("media-container")) globalThis.customElements.define("media-container", MediaContainer);
|
|
1407
|
-
|
|
1408
|
-
//#endregion
|
|
1409
|
-
//#region src/media/media-provider.ts
|
|
1410
|
-
const ProviderHTMLElement = ProviderMixin(HTMLElement);
|
|
1411
|
-
var MediaProvider = class extends ProviderHTMLElement {
|
|
1412
|
-
constructor(..._args) {
|
|
1413
|
-
super(..._args);
|
|
1414
|
-
this.contexts = { mediaStore: () => {
|
|
1415
|
-
return createMediaStore();
|
|
1416
|
-
} };
|
|
1417
|
-
}
|
|
1418
|
-
};
|
|
1419
|
-
customElements.define("media-provider", MediaProvider);
|
|
1420
|
-
|
|
1421
|
-
//#endregion
|
|
1422
|
-
//#region src/media/media-skin.ts
|
|
1423
|
-
function getTemplateHTML() {
|
|
1424
|
-
return `
|
|
1425
|
-
<style>
|
|
1426
|
-
:host {
|
|
1427
|
-
display: block;
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
media-container {
|
|
1431
|
-
display: block;
|
|
1432
|
-
width: 100%;
|
|
1433
|
-
height: 100%;
|
|
1434
|
-
}
|
|
1435
|
-
</style>
|
|
1436
|
-
<slot></slot>
|
|
1437
|
-
`;
|
|
1438
|
-
}
|
|
1439
|
-
var MediaSkin = class extends HTMLElement {
|
|
1440
|
-
static {
|
|
1441
|
-
this.shadowRootOptions = { mode: "open" };
|
|
1442
|
-
}
|
|
1443
|
-
static {
|
|
1444
|
-
this.getTemplateHTML = getTemplateHTML;
|
|
1445
|
-
}
|
|
1446
|
-
constructor() {
|
|
1447
|
-
super();
|
|
1448
|
-
if (!this.shadowRoot) {
|
|
1449
|
-
this.attachShadow(this.constructor.shadowRootOptions);
|
|
1450
|
-
this.shadowRoot.innerHTML = this.constructor.getTemplateHTML();
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
};
|
|
1454
|
-
if (!customElements.get("media-skin")) customElements.define("media-skin", MediaSkin);
|
|
1455
|
-
|
|
1456
|
-
//#endregion
|
|
1457
|
-
export { Tooltip as a, PlayButton as c, DurationDisplay as d, CurrentTimeDisplay as f, VolumeSlider$1 as i, MuteButton as l, MediaProvider as n, TimeSlider$1 as o, toConnectedHTMLComponent as p, MediaContainer as r, Popover as s, MediaSkin as t, FullscreenButton as u };
|
|
1458
|
-
//# sourceMappingURL=media-skin-BlXPC9wG.js.map
|