Google has introduced the documentPictureInPicture API in chrome 116.
In this article we explore how to mount a simple react component in the picture in picture window without the need to first mount it on our main application.
Step 1 — Set up component structure
We make two components. MainComponent.js and Counter.js. In MainComponent.js we set up a simple button that will open up the Counter.js component in the PIP window.
MainComponent.js
import React from "react";
const MainComponent = () => {
async function openPictureInPicture() {
//
}
return (
<div>
<div onClick={openPictureInPicture}>Open counter</div>
</div>
);
};
export default MainComponent;
Counter.js
import React, { useState, useEffect } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(1);
}, []);
const addNumber = () => {
setCount((prevCount) => prevCount + 1);
};
const subtractNumber = () => {
setCount((prevCount) => prevCount - 1);
};
try {
return (
<div>
<div onClick={subtractNumber}>-</div>
<button>{count}</button>
<div onClick={addNumber}>+</div>
</div>
);
} catch (error) {
console.error("ERROR_CODE: _RENDER\n", error);
return <></>;
}
};
export default Counter;
Step 2 — Add the picture in picture functionality
In the openPictureInPicture() function we request for a picture in picture window.
const pipWindow = await window.documentPictureInPicture.requestWindow();
We create a div element in the body of the pip window. On this div we will mount our Counter.js
const pipDiv = pipWindow.document.createElement("div");
pipDiv.setAttribute("id", "pip-root");
pipWindow.document.body.append(pipDiv);
Now we mount our Counter.js component on the div with id “pip-root”.
const PIP_ROOT = ReactDOM.createRoot(
pipWindow.document.getElementById("pip-root")
);
PIP_ROOT.render(<Counter />);
Step 3 — Combining it all
The final MainComponent.js code should look something like this.
import React from "react";
import Counter from "./Counter";
import ReactDOM from "react-dom/client";
const MainComponent = () => {
async function openPictureInPicture() {
const pipWindow = await window.documentPictureInPicture.requestWindow();
const pipDiv = pipWindow.document.createElement("div");
pipDiv.setAttribute("id", "pip-root");
pipWindow.document.body.append(pipDiv);
const PIP_ROOT = ReactDOM.createRoot(pipWindow.document.getElementById("pip-root"));
PIP_ROOT.render(<Counter />);
}
return (
<div>
<div onClick={openPictureInPicture}>Open counter</div>
</div>
);
};
export default MainComponent;
Now we have our own react component mounting on a picture in picture window!
Top comments (0)