diff --git a/packages/core/src/dom/store/features/controls.ts b/packages/core/src/dom/store/features/controls.ts
index da3e967e..477e4d7a 100644
--- a/packages/core/src/dom/store/features/controls.ts
+++ b/packages/core/src/dom/store/features/controls.ts
@@ -62,9 +62,10 @@ export const controlsFeature = definePlayerFeature({
function onPointerUp(event: PointerEvent) {
if (event.pointerType === 'touch' && Date.now() - pointerDownTime < TAP_THRESHOLD) {
- if (get().controlsVisible) {
- clearIdle();
- set({ userActive: false, controlsVisible: computeVisible(false) });
+ // If the event target is in the controls don't set inactive because that sets pointer-events: none in CSS.
+ const isMediaOrContainer = [media, container].includes(event.target as HTMLElement);
+ if (get().controlsVisible && isMediaOrContainer) {
+ setInactive();
} else {
setActive();
}
@@ -90,7 +91,9 @@ export const controlsFeature = definePlayerFeature({
listen(container, 'pointerup', onPointerUp, { signal });
listen(container, 'keyup', setActive, { signal });
listen(container, 'focusin', setActive, { signal });
- listen(container, 'pointerleave', setInactive, { signal });
+ // On touch devices pointerleave would fire after a pointerup event which hides the controls.
+ // https://w3c.github.io/pointerevents/#dfn-pointerup
+ listen(container, 'mouseleave', setInactive, { signal });
// Media event listeners for playback state changes.
listen(media, 'play', onPlaybackChange, { signal });
diff --git a/packages/core/src/dom/store/features/tests/controls.test.ts b/packages/core/src/dom/store/features/tests/controls.test.ts
index d23452f0..8a0de63c 100644
--- a/packages/core/src/dom/store/features/tests/controls.test.ts
+++ b/packages/core/src/dom/store/features/tests/controls.test.ts
@@ -123,22 +123,22 @@ describe('controlsFeature', () => {
expect(store.state.userActive).toBe(true);
});
- it('sets inactive immediately on pointerleave', () => {
+ it('sets inactive immediately on mouseleave', () => {
const video = createMockVideo({ paused: false });
const { store, container } = createPlayerStore(video);
- container!.dispatchEvent(new Event('pointerleave'));
+ container!.dispatchEvent(new Event('mouseleave'));
flush();
expect(store.state.userActive).toBe(false);
expect(store.state.controlsVisible).toBe(false);
});
- it('keeps controlsVisible true on pointerleave when paused', () => {
+ it('keeps controlsVisible true on mouseleave when paused', () => {
const video = createMockVideo({ paused: true });
const { store, container } = createPlayerStore(video);
- container!.dispatchEvent(new Event('pointerleave'));
+ container!.dispatchEvent(new Event('mouseleave'));
flush();
expect(store.state.userActive).toBe(false);
diff --git a/packages/sandbox/templates/html-hls-video/main.ts b/packages/sandbox/templates/html-hls-video/main.ts
index 3714f744..1e2a7496 100644
--- a/packages/sandbox/templates/html-hls-video/main.ts
+++ b/packages/sandbox/templates/html-hls-video/main.ts
@@ -23,7 +23,7 @@ function render() {
document.getElementById('root')!.innerHTML = html`
<${tag} class="w-full aspect-video max-w-4xl mx-auto">
-
+
${tag}>
`;
diff --git a/packages/sandbox/templates/html-simple-hls-video/main.ts b/packages/sandbox/templates/html-simple-hls-video/main.ts
index 92ffec9f..bf8f676d 100644
--- a/packages/sandbox/templates/html-simple-hls-video/main.ts
+++ b/packages/sandbox/templates/html-simple-hls-video/main.ts
@@ -23,7 +23,7 @@ function render() {
document.getElementById('root')!.innerHTML = html`
<${tag} class="w-full aspect-video max-w-4xl mx-auto">
-
+
${tag}>
`;
diff --git a/packages/sandbox/templates/html-video-tailwind/main.ts b/packages/sandbox/templates/html-video-tailwind/main.ts
index ea011db3..20a47644 100644
--- a/packages/sandbox/templates/html-video-tailwind/main.ts
+++ b/packages/sandbox/templates/html-video-tailwind/main.ts
@@ -22,7 +22,7 @@ function render() {
document.getElementById('root')!.innerHTML = html`
<${tag} class="w-full aspect-video max-w-4xl mx-auto">
-
+
${tag}>
`;
diff --git a/packages/sandbox/templates/html-video/main.ts b/packages/sandbox/templates/html-video/main.ts
index 11260f30..883b911f 100644
--- a/packages/sandbox/templates/html-video/main.ts
+++ b/packages/sandbox/templates/html-video/main.ts
@@ -22,7 +22,7 @@ function render() {
document.getElementById('root')!.innerHTML = html`
<${tag} class="w-full aspect-video max-w-4xl mx-auto">
-
+
${tag}>
`;
diff --git a/packages/sandbox/templates/react-hls-video/main.tsx b/packages/sandbox/templates/react-hls-video/main.tsx
index f9e2e17b..2fa205e5 100644
--- a/packages/sandbox/templates/react-hls-video/main.tsx
+++ b/packages/sandbox/templates/react-hls-video/main.tsx
@@ -16,7 +16,7 @@ function App() {
return (
-
+
);
diff --git a/packages/sandbox/templates/react-simple-hls-video/main.tsx b/packages/sandbox/templates/react-simple-hls-video/main.tsx
index 0f9d44eb..b1bcc103 100644
--- a/packages/sandbox/templates/react-simple-hls-video/main.tsx
+++ b/packages/sandbox/templates/react-simple-hls-video/main.tsx
@@ -16,7 +16,7 @@ function App() {
return (
-
+
);
diff --git a/packages/sandbox/templates/react-video-tailwind/main.tsx b/packages/sandbox/templates/react-video-tailwind/main.tsx
index 2e043669..7d88e38c 100644
--- a/packages/sandbox/templates/react-video-tailwind/main.tsx
+++ b/packages/sandbox/templates/react-video-tailwind/main.tsx
@@ -14,7 +14,7 @@ function App() {
return (
-
+
);
diff --git a/packages/sandbox/templates/react-video/main.tsx b/packages/sandbox/templates/react-video/main.tsx
index ab2b1ab5..82920010 100644
--- a/packages/sandbox/templates/react-video/main.tsx
+++ b/packages/sandbox/templates/react-video/main.tsx
@@ -16,7 +16,7 @@ function App() {
return (
-
+
);