<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Saurabh Shakya</title>
    <description>The latest articles on DEV Community by Saurabh Shakya (@shakya47).</description>
    <link>https://dev.to/shakya47</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3940655%2F5a08d9a6-2bfc-4c2e-b3b4-dc42ec24dfa5.png</url>
      <title>DEV Community: Saurabh Shakya</title>
      <link>https://dev.to/shakya47</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shakya47"/>
    <language>en</language>
    <item>
      <title>Pop any UI component into a floating Picture-in-Picture window.</title>
      <dc:creator>Saurabh Shakya</dc:creator>
      <pubDate>Tue, 19 May 2026 19:46:18 +0000</pubDate>
      <link>https://dev.to/shakya47/pop-any-ui-component-into-a-floating-picture-in-picture-window-3ebl</link>
      <guid>https://dev.to/shakya47/pop-any-ui-component-into-a-floating-picture-in-picture-window-3ebl</guid>
      <description>&lt;p&gt;Project: &lt;a href="https://pip-it-up.vercel.app" rel="noopener noreferrer"&gt;pip-it-up&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jpib3mj88d6m52xhuic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jpib3mj88d6m52xhuic.png" alt=" " width="799" height="576"&gt;&lt;/a&gt;  &lt;/p&gt;
&lt;h1&gt;
  
  
  Why is Picture-in-Picture only for video? Bringing native PiP to React components with pip-it-up
&lt;/h1&gt;

&lt;p&gt;We all love Video Picture-in-Picture. Whether it's watching a live stream on the side or catching up on a tutorial while you work, floating windows are incredibly useful. But it begs a simple question: why should video have all the fun?&lt;/p&gt;

&lt;p&gt;Why can't we have native PiP for &lt;em&gt;individual UI components&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;As a developer who prefers the clean focus of a single-screen setup, I was tired of tab-switching. I wanted a way to tear away just a small, specific part of my web application a markdown editor, a task list, a diagnostic log viewer and stick it always-on-top of my IDE without losing context or breaking my flow.&lt;/p&gt;

&lt;p&gt;This is the story of how I built &lt;strong&gt;pip-it-up&lt;/strong&gt;: an open-source React toolkit for the browser's Document Picture-in-Picture API.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Document PiP API: more powerful than you think
&lt;/h2&gt;

&lt;p&gt;Most developers are familiar with the standard Video Picture-in-Picture API. It lets you pop a &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; element into a small floating window that stays on top of everything else on your screen. Useful, but limited it only works with video.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Picture-in-Picture_API" rel="noopener noreferrer"&gt;&lt;strong&gt;Document Picture-in-Picture API&lt;/strong&gt;&lt;/a&gt; is a different beast entirely. Instead of floating a video element, it opens a fully functional floating browser window that can contain &lt;em&gt;any&lt;/em&gt; interactive HTML content. Buttons, inputs, iframes, canvas elements, React components all of it works inside a real, always-on-top floating window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The raw browser API&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pipWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentPictureInPicture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;requestWindow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Move any DOM node into it&lt;/span&gt;
&lt;span class="nx"&gt;pipWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On paper this is exactly what we need. In practice, using it directly in a React application is where things get painful.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three engineering roadblocks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. CSS stylesheet isolation
&lt;/h3&gt;

&lt;p&gt;When you open a new PiP window, you get a completely blank document. Your Tailwind utility classes? Gone. Your Emotion or Styled Components rules? Gone. Your CSS Modules? Gone.&lt;/p&gt;

&lt;p&gt;The PiP window has its own &lt;code&gt;document&lt;/code&gt; object with its own &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;. None of the stylesheets from your main application are inherited, which means the moment you move a component into the PiP window, it renders as completely unstyled raw HTML.&lt;/p&gt;

&lt;p&gt;This isn't a minor visual glitch, it completely breaks the component.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. DOM moving vs. virtual DOM state
&lt;/h3&gt;

&lt;p&gt;Here's where things get subtle. When you physically move a DOM node from one document into another (which is what the raw API requires), the browser treats it as a brand new element. For vanilla JavaScript this is manageable, but for React it's a disaster.&lt;/p&gt;

&lt;p&gt;React's reconciler tracks component identity through the virtual DOM tree. When you physically reparent a DOM node into a new document, React loses track of it. The result: the component unmounts and remounts, which wipes all internal state, breaks event listeners, resets scroll positions, resets input cursor positions, and kills any active audio or animation state.&lt;/p&gt;

&lt;p&gt;If you had a text input with a cursor halfway through a word, it's gone. If you had a Monaco editor open with unsaved changes, it's gone.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Browser support
&lt;/h3&gt;

&lt;p&gt;The Document PiP API is currently supported in Chrome 116+ and Edge 116+. Firefox and Safari do not support it at all. Without a fallback strategy, your application simply breaks for a significant chunk of your users.&lt;/p&gt;




&lt;h2&gt;
  
  
  How pip-it-up solves all three
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Real-time style syncing
&lt;/h3&gt;

&lt;p&gt;Instead of hoping styles somehow transfer, pip-it-up uses a &lt;code&gt;MutationObserver&lt;/code&gt; to watch your main document's &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; for any &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;link rel="stylesheet"&amp;gt;&lt;/code&gt; additions or changes, then dynamically clones and mirrors them into the PiP window's document in real time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MutationObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addedNodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;STYLE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LINK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;pipWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cloneNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;childList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;subtree&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means Tailwind utilities, CSS-in-JS injected styles, and CSS Modules all work perfectly inside the floating window. The sync is live, if a new stylesheet is injected after the PiP window opens, it gets mirrored automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Virtual tree retention via React Portals
&lt;/h3&gt;

&lt;p&gt;This is the core architectural insight of pip-it-up. Instead of destroying and recreating the React component in the new window, we use a &lt;strong&gt;React Portal&lt;/strong&gt; to physically move the DOM node into the PiP window while keeping the virtual component instance exactly where it was in the tree.&lt;/p&gt;

&lt;p&gt;The component never unmounts. React never loses track of it. All context, all state, all event handlers, all cursor positions remain perfectly intact. The component just happens to be rendering its DOM into a different document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simplified version of how Portal Mode works&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PipPortal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;pipWindow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;pipWindow&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;createPortal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pipWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From React's perspective nothing changed. From the user's perspective, the component is now floating on top of their IDE.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smart auto-sizing with ResizeObserver
&lt;/h3&gt;

&lt;p&gt;The raw Document PiP API requires you to specify explicit &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; values when opening the window. This means you'd normally need to hardcode dimensions or manually pass them as props — a poor developer experience.&lt;/p&gt;

&lt;p&gt;pip-it-up attaches a &lt;code&gt;ResizeObserver&lt;/code&gt; to the component being floated and automatically measures its natural dimensions before opening the PiP window, then keeps the window dimensions in sync as the component resizes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resizeObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResizeObserver&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentRect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Sync PiP window dimensions automatically&lt;/span&gt;
  &lt;span class="nx"&gt;pipWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizeTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;resizeObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;width&lt;/code&gt; or &lt;code&gt;height&lt;/code&gt; props required. It just works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graceful fallbacks for Firefox and Safari
&lt;/h3&gt;

&lt;p&gt;When the Document PiP API isn't available, pip-it-up automatically detects this and falls back to a customizable popup, modal, or inline UI whatever you configure. Your users on Firefox and Safari never see a broken page; they just get a slightly different (but fully functional) experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using it in your project
&lt;/h2&gt;

&lt;p&gt;Installation is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @pip-it-up/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic usage with PipWrapper and PipTrigger
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PipWrapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PipTrigger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@pip-it-up/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PipWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PipTrigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Float this widget&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PipTrigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"my-widget"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Reference Checklist&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Review PR comments&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Run test suite&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Update changelog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PipWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user clicks the trigger, the widget tears away into a native always-on-top floating window. Click it again and it snaps back with all its state perfectly preserved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Floating a Monaco editor with state preservation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PipWrapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PipTrigger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@pip-it-up/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Editor&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@monaco-editor/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CodePanel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCode&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;// Start coding...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PipWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PipTrigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Pop out editor&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PipTrigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Editor&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"400px"&lt;/span&gt;
        &lt;span class="na"&gt;defaultLanguage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"javascript"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setCode&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;PipWrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The editor floats into a native PiP window. Your cursor position, selection state, scroll position, and the code itself all survive the transition perfectly. You can type in the floating editor while your main application is focused in another window.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you can build with this
&lt;/h2&gt;

&lt;p&gt;A few ideas to get you thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Floating reference panels&lt;/strong&gt;: Keep a keyboard shortcut cheatsheet or API reference visible while you work in your IDE&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tear-away chat widgets&lt;/strong&gt;: Pop a support chat or team messaging widget out of a SaaS tool and keep it on-screen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Floating code playgrounds&lt;/strong&gt;: Let users experiment with code in a persistent floating window&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always-on-top dashboards&lt;/strong&gt;: Pin a metrics panel or log viewer on top of your development environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent note-taking&lt;/strong&gt;: Float a scratchpad widget that stays accessible regardless of what you're focused on&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The live playground has interactive demos including a floating Monaco editor, a Tailwind layout widget, and a keyboard shortcut manager all showing real state preservation in action.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Playground:&lt;/strong&gt; &lt;a href="https://pip-it-up.vercel.app/" rel="noopener noreferrer"&gt;pip-it-up.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub (MIT):&lt;/strong&gt; &lt;a href="https://github.com/Shakya47/pip-it-up" rel="noopener noreferrer"&gt;github.com/Shakya47/pip-it-up&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NPM:&lt;/strong&gt; &lt;code&gt;npm i @pip-it-up/react&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you prefer a focused, single-screen workflow, I hope this helps you stay in the zone. And if you build something interesting with it, I'd genuinely love to hear about it in the comments.&lt;/p&gt;

&lt;p&gt;What's the first component you'd float?&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
