@tanstack/query-devtools 5.21.5 → 5.23.0

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.
@@ -9073,6 +9073,21 @@ function Settings() {
9073
9073
  />
9074
9074
  </svg>;
9075
9075
  }
9076
+ function PiPIcon() {
9077
+ return <svg
9078
+ width="24"
9079
+ height="24"
9080
+ viewBox="0 0 24 24"
9081
+ fill="none"
9082
+ xmlns="http://www.w3.org/2000/svg"
9083
+ ><path
9084
+ d="M16 21H16.2C17.8802 21 18.7202 21 19.362 20.673C19.9265 20.3854 20.3854 19.9265 20.673 19.362C21 18.7202 21 17.8802 21 16.2V7.8C21 6.11984 21 5.27976 20.673 4.63803C20.3854 4.07354 19.9265 3.6146 19.362 3.32698C18.7202 3 17.8802 3 16.2 3H7.8C6.11984 3 5.27976 3 4.63803 3.32698C4.07354 3.6146 3.6146 4.07354 3.32698 4.63803C3 5.27976 3 6.11984 3 7.8V8M11.5 12.5L17 7M17 7H12M17 7V12M6.2 21H8.8C9.9201 21 10.4802 21 10.908 20.782C11.2843 20.5903 11.5903 20.2843 11.782 19.908C12 19.4802 12 18.9201 12 17.8V15.2C12 14.0799 12 13.5198 11.782 13.092C11.5903 12.7157 11.2843 12.4097 10.908 12.218C10.4802 12 9.92011 12 8.8 12H6.2C5.0799 12 4.51984 12 4.09202 12.218C3.71569 12.4097 3.40973 12.7157 3.21799 13.092C3 13.5198 3 14.0799 3 15.2V17.8C3 18.9201 3 19.4802 3.21799 19.908C3.40973 20.2843 3.71569 20.5903 4.09202 20.782C4.51984 21 5.07989 21 6.2 21Z"
9085
+ stroke="currentColor"
9086
+ stroke-width="2"
9087
+ stroke-linecap="round"
9088
+ stroke-linejoin="round"
9089
+ /></svg>;
9090
+ }
9076
9091
  function Copier() {
9077
9092
  return <svg
9078
9093
  width="24"
@@ -10435,6 +10450,124 @@ var [selectedMutationId, setSelectedMutationId] = createSignal(
10435
10450
  null
10436
10451
  );
10437
10452
  var [panelWidth, setPanelWidth] = createSignal(0);
10453
+ var PiPContext = createContext(
10454
+ void 0
10455
+ );
10456
+ var PiPProvider = (props) => {
10457
+ const [pipWindow, setPipWindow] = createSignal(null);
10458
+ const closePipWindow = () => {
10459
+ const w = pipWindow();
10460
+ if (w != null) {
10461
+ w.close();
10462
+ setPipWindow(null);
10463
+ }
10464
+ };
10465
+ const requestPipWindow = async (width, height) => {
10466
+ if (pipWindow() != null) {
10467
+ return;
10468
+ }
10469
+ const pip = window.open("", "", `width=${width},height=${height},popup`);
10470
+ if (!pip) {
10471
+ throw new Error(
10472
+ "Failed to open popup. Please allow popups for this site to view the devtools in picture-in-picture mode."
10473
+ );
10474
+ }
10475
+ pip.document.title = "TanStack Query Devtools";
10476
+ pip.document.body.style.margin = "0";
10477
+ pip.addEventListener("pagehide", () => {
10478
+ setPipWindow(null);
10479
+ });
10480
+ [...document.styleSheets].forEach((styleSheet) => {
10481
+ try {
10482
+ const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join("");
10483
+ const style2 = document.createElement("style");
10484
+ const style_node = styleSheet.ownerNode;
10485
+ let style_id = "";
10486
+ if (style_node && "id" in style_node) {
10487
+ style_id = style_node.id;
10488
+ }
10489
+ if (style_id) {
10490
+ style2.setAttribute("id", style_id);
10491
+ }
10492
+ style2.textContent = cssRules;
10493
+ pip.document.head.appendChild(style2);
10494
+ } catch (e2) {
10495
+ const link = document.createElement("link");
10496
+ if (styleSheet.href == null) {
10497
+ return;
10498
+ }
10499
+ link.rel = "stylesheet";
10500
+ link.type = styleSheet.type;
10501
+ link.media = styleSheet.media.toString();
10502
+ link.href = styleSheet.href;
10503
+ pip.document.head.appendChild(link);
10504
+ }
10505
+ });
10506
+ delegateEvents(
10507
+ [
10508
+ "focusin",
10509
+ "focusout",
10510
+ "pointermove",
10511
+ "keydown",
10512
+ "pointerdown",
10513
+ "pointerup",
10514
+ "click",
10515
+ "mousedown",
10516
+ "input"
10517
+ ],
10518
+ pip.document
10519
+ );
10520
+ setPipWindow(pip);
10521
+ };
10522
+ createEffect(() => {
10523
+ const closePipWindowOnUnload = () => {
10524
+ closePipWindow();
10525
+ };
10526
+ window.addEventListener("beforeunload", closePipWindowOnUnload);
10527
+ onCleanup(() => {
10528
+ window.removeEventListener("beforeunload", closePipWindowOnUnload);
10529
+ });
10530
+ });
10531
+ createEffect(() => {
10532
+ const gooberStyles = document.getElementById("_goober");
10533
+ const w = pipWindow();
10534
+ if (gooberStyles && w) {
10535
+ const observer = new MutationObserver(() => {
10536
+ const pip_style = w.document.getElementById("_goober");
10537
+ if (pip_style) {
10538
+ pip_style.textContent = gooberStyles.textContent;
10539
+ }
10540
+ });
10541
+ observer.observe(gooberStyles, {
10542
+ childList: true,
10543
+ // observe direct children
10544
+ subtree: true,
10545
+ // and lower descendants too
10546
+ characterDataOldValue: true
10547
+ // pass old data to callback
10548
+ });
10549
+ onCleanup(() => {
10550
+ observer.disconnect();
10551
+ });
10552
+ }
10553
+ });
10554
+ const value = createMemo(() => ({
10555
+ pipWindow: pipWindow(),
10556
+ requestPipWindow,
10557
+ closePipWindow
10558
+ }));
10559
+ return <PiPContext.Provider value={value}>{props.children}</PiPContext.Provider>;
10560
+ };
10561
+ var usePiPWindow = () => {
10562
+ const context = createMemo(() => {
10563
+ const ctx = useContext(PiPContext);
10564
+ if (!ctx) {
10565
+ throw new Error("usePiPWindow must be used within a PiPProvider");
10566
+ }
10567
+ return ctx();
10568
+ });
10569
+ return context;
10570
+ };
10438
10571
  var DevtoolsComponent = (props) => {
10439
10572
  const [localStore, setLocalStore] = createLocalStorage({
10440
10573
  prefix: "TanstackQueryDevtools"
@@ -10446,7 +10579,7 @@ var DevtoolsComponent = (props) => {
10446
10579
  return preference;
10447
10580
  return colorScheme();
10448
10581
  });
10449
- return <QueryDevtoolsContext.Provider value={props}><ThemeContext.Provider value={theme}><Devtools localStore={localStore} setLocalStore={setLocalStore} /></ThemeContext.Provider></QueryDevtoolsContext.Provider>;
10582
+ return <QueryDevtoolsContext.Provider value={props}><PiPProvider><ThemeContext.Provider value={theme}><Devtools localStore={localStore} setLocalStore={setLocalStore} /></ThemeContext.Provider></PiPProvider></QueryDevtoolsContext.Provider>;
10450
10583
  };
10451
10584
  var Devtools_default = DevtoolsComponent;
10452
10585
  var Devtools = (props) => {
@@ -10454,6 +10587,7 @@ var Devtools = (props) => {
10454
10587
  const styles = createMemo(() => {
10455
10588
  return theme() === "dark" ? darkStyles2 : lightStyles2;
10456
10589
  });
10590
+ const pip = usePiPWindow();
10457
10591
  const buttonPosition = createMemo(() => {
10458
10592
  return useQueryDevtoolsContext().buttonPosition || BUTTON_POSITION;
10459
10593
  });
@@ -10490,58 +10624,119 @@ var Devtools = (props) => {
10490
10624
  window.removeEventListener("focus", onFocus);
10491
10625
  });
10492
10626
  });
10493
- return <div
10494
- class={clsx(
10495
- u`
10496
- & .tsqd-panel-transition-exit-active,
10497
- & .tsqd-panel-transition-enter-active {
10498
- transition:
10499
- opacity 0.3s,
10500
- transform 0.3s;
10501
- }
10502
-
10503
- & .tsqd-panel-transition-exit-to,
10504
- & .tsqd-panel-transition-enter {
10505
- ${position() === "top" || position() === "bottom" ? `transform: translateY(var(--tsqd-panel-height));` : `transform: translateX(var(--tsqd-panel-width));`}
10506
- }
10507
-
10508
- & .tsqd-button-transition-exit-active,
10509
- & .tsqd-button-transition-enter-active {
10510
- transition:
10511
- opacity 0.3s,
10512
- transform 0.3s;
10513
- opacity: 1;
10514
- }
10515
-
10516
- & .tsqd-button-transition-exit-to,
10517
- & .tsqd-button-transition-enter {
10518
- transform: ${buttonPosition() === "relative" ? `none;` : buttonPosition() === "top-left" ? `translateX(-72px);` : buttonPosition() === "top-right" ? `translateX(72px);` : `translateY(72px);`};
10519
- opacity: 0;
10520
- }
10521
- `,
10522
- "tsqd-transitions-container"
10523
- )}
10524
- ref={transitionsContainerRef}
10525
- >
10526
- <TransitionGroup name="tsqd-panel-transition"><Show when={isOpen()}><DevtoolsPanel
10627
+ return <>
10628
+ <Show when={pip().pipWindow}><Portal mount={pip().pipWindow?.document.body}><PiPPanel><ContentView
10527
10629
  localStore={props.localStore}
10528
10630
  setLocalStore={props.setLocalStore}
10529
- /></Show></TransitionGroup>
10530
- <TransitionGroup name="tsqd-button-transition"><Show when={!isOpen()}><div
10631
+ /></PiPPanel></Portal></Show>
10632
+ <div
10531
10633
  class={clsx(
10532
- styles().devtoolsBtn,
10533
- styles()[`devtoolsBtn-position-${buttonPosition()}`],
10534
- "tsqd-open-btn-container"
10634
+ u`
10635
+ & .tsqd-panel-transition-exit-active,
10636
+ & .tsqd-panel-transition-enter-active {
10637
+ transition:
10638
+ opacity 0.3s,
10639
+ transform 0.3s;
10640
+ }
10641
+
10642
+ & .tsqd-panel-transition-exit-to,
10643
+ & .tsqd-panel-transition-enter {
10644
+ ${position() === "top" || position() === "bottom" ? `transform: translateY(var(--tsqd-panel-height));` : `transform: translateX(var(--tsqd-panel-width));`}
10645
+ }
10646
+
10647
+ & .tsqd-button-transition-exit-active,
10648
+ & .tsqd-button-transition-enter-active {
10649
+ transition:
10650
+ opacity 0.3s,
10651
+ transform 0.3s;
10652
+ opacity: 1;
10653
+ }
10654
+
10655
+ & .tsqd-button-transition-exit-to,
10656
+ & .tsqd-button-transition-enter {
10657
+ transform: ${buttonPosition() === "relative" ? `none;` : buttonPosition() === "top-left" ? `translateX(-72px);` : buttonPosition() === "top-right" ? `translateX(72px);` : `translateY(72px);`};
10658
+ opacity: 0;
10659
+ }
10660
+ `,
10661
+ "tsqd-transitions-container"
10535
10662
  )}
10663
+ ref={transitionsContainerRef}
10536
10664
  >
10537
- <div aria-hidden="true"><TanstackLogo /></div>
10538
- <button
10539
- aria-label="Open Tanstack query devtools"
10540
- onClick={() => props.setLocalStore("open", "true")}
10541
- class="tsqd-open-btn"
10542
- ><TanstackLogo /></button>
10543
- </div></Show></TransitionGroup>
10544
- </div>;
10665
+ <TransitionGroup name="tsqd-panel-transition"><Show when={isOpen() && !pip().pipWindow}><DevtoolsPanel
10666
+ localStore={props.localStore}
10667
+ setLocalStore={props.setLocalStore}
10668
+ /></Show></TransitionGroup>
10669
+ <TransitionGroup name="tsqd-button-transition"><Show when={!isOpen()}><div
10670
+ class={clsx(
10671
+ styles().devtoolsBtn,
10672
+ styles()[`devtoolsBtn-position-${buttonPosition()}`],
10673
+ "tsqd-open-btn-container"
10674
+ )}
10675
+ >
10676
+ <div aria-hidden="true"><TanstackLogo /></div>
10677
+ <button
10678
+ aria-label="Open Tanstack query devtools"
10679
+ onClick={() => props.setLocalStore("open", "true")}
10680
+ class="tsqd-open-btn"
10681
+ ><TanstackLogo /></button>
10682
+ </div></Show></TransitionGroup>
10683
+ </div>
10684
+ </>;
10685
+ };
10686
+ var PiPPanel = (props) => {
10687
+ const pip = usePiPWindow();
10688
+ const theme = useTheme();
10689
+ const styles = createMemo(() => {
10690
+ return theme() === "dark" ? darkStyles2 : lightStyles2;
10691
+ });
10692
+ const getPanelDynamicStyles = () => {
10693
+ const { colors } = tokens;
10694
+ const t2 = (light, dark) => theme() === "dark" ? dark : light;
10695
+ if (panelWidth() < secondBreakpoint) {
10696
+ return u`
10697
+ flex-direction: column;
10698
+ background-color: ${t2(colors.gray[300], colors.gray[600])};
10699
+ `;
10700
+ }
10701
+ return u`
10702
+ flex-direction: row;
10703
+ background-color: ${t2(colors.gray[200], colors.darkGray[900])};
10704
+ `;
10705
+ };
10706
+ createEffect(() => {
10707
+ const win = pip().pipWindow;
10708
+ const resizeCB = () => {
10709
+ if (!win)
10710
+ return;
10711
+ setPanelWidth(win.innerWidth);
10712
+ };
10713
+ if (win) {
10714
+ win.addEventListener("resize", resizeCB);
10715
+ }
10716
+ onCleanup(() => {
10717
+ if (win) {
10718
+ win.removeEventListener("resize", resizeCB);
10719
+ }
10720
+ });
10721
+ });
10722
+ return <div
10723
+ style={{
10724
+ "--tsqd-font-size": "16px",
10725
+ "max-height": "100vh",
10726
+ height: "100vh",
10727
+ width: "100vw"
10728
+ }}
10729
+ class={clsx(
10730
+ styles().panel,
10731
+ getPanelDynamicStyles(),
10732
+ {
10733
+ [u`
10734
+ min-width: min-content;
10735
+ `]: panelWidth() < thirdBreakpoint
10736
+ },
10737
+ "tsqd-main-panel"
10738
+ )}
10739
+ >{props.children}</div>;
10545
10740
  };
10546
10741
  var DevtoolsPanel = (props) => {
10547
10742
  const theme = useTheme();
@@ -10695,6 +10890,7 @@ var ContentView = (props) => {
10695
10890
  const styles = createMemo(() => {
10696
10891
  return theme() === "dark" ? darkStyles2 : lightStyles2;
10697
10892
  });
10893
+ const pip = usePiPWindow();
10698
10894
  const [selectedView, setSelectedView] = createSignal(
10699
10895
  "queries"
10700
10896
  );
@@ -10793,7 +10989,11 @@ var ContentView = (props) => {
10793
10989
  <div class={styles().logoAndToggleContainer}>
10794
10990
  <button
10795
10991
  class={clsx(styles().logo, "tsqd-text-logo-container")}
10796
- onClick={() => props.setLocalStore("open", "false")}
10992
+ onClick={() => {
10993
+ if (!pip().pipWindow) {
10994
+ props.setLocalStore("open", "false");
10995
+ }
10996
+ }}
10797
10997
  aria-label="Close Tanstack query devtools"
10798
10998
  >
10799
10999
  <span
@@ -10854,7 +11054,7 @@ var ContentView = (props) => {
10854
11054
  props.setLocalStore("mutationFilter", e2.currentTarget.value);
10855
11055
  }
10856
11056
  }}
10857
- class="tsqd-query-filter-textfield"
11057
+ class={clsx("tsqd-query-filter-textfield")}
10858
11058
  name="tsqd-query-filter-input"
10859
11059
  value={selectedView() === "queries" ? props.localStore.filter || "" : props.localStore.mutationFilter || ""}
10860
11060
  />
@@ -10953,6 +11153,21 @@ var ContentView = (props) => {
10953
11153
  aria-pressed={offline()}
10954
11154
  title={`${offline() ? "Unset offline mocking behavior" : "Mock offline behavior"}`}
10955
11155
  >{offline() ? <Offline /> : <Wifi />}</button>
11156
+ <Show when={!pip().pipWindow}><button
11157
+ onClick={() => {
11158
+ pip().requestPipWindow(
11159
+ Number(window.innerWidth),
11160
+ Number(props.localStore.height ?? 500)
11161
+ );
11162
+ }}
11163
+ class={clsx(
11164
+ styles().actionsBtn,
11165
+ "tsqd-actions-btn",
11166
+ "tsqd-action-open-pip"
11167
+ )}
11168
+ aria-label="Open in picture-in-picture mode"
11169
+ title="Open in picture-in-picture mode"
11170
+ ><PiPIcon /></button></Show>
10956
11171
  <index$f.Root gutter={4}>
10957
11172
  <index$f.Trigger
10958
11173
  class={clsx(
@@ -10963,6 +11178,7 @@ var ContentView = (props) => {
10963
11178
  ><Settings /></index$f.Trigger>
10964
11179
  <index$f.Portal
10965
11180
  ref={(el) => setComputedVariables(el)}
11181
+ mount={pip().pipWindow ? pip().pipWindow.document.body : document.body}
10966
11182
  ><index$f.Content
10967
11183
  class={clsx(styles().settingsMenu, "tsqd-settings-menu")}
10968
11184
  >
@@ -10985,6 +11201,7 @@ var ContentView = (props) => {
10985
11201
  </index$f.SubTrigger>
10986
11202
  <index$f.Portal
10987
11203
  ref={(el) => setComputedVariables(el)}
11204
+ mount={pip().pipWindow ? pip().pipWindow.document.body : document.body}
10988
11205
  ><index$f.SubContent
10989
11206
  class={clsx(
10990
11207
  styles().settingsMenu,
@@ -11062,6 +11279,7 @@ var ContentView = (props) => {
11062
11279
  </index$f.SubTrigger>
11063
11280
  <index$f.Portal
11064
11281
  ref={(el) => setComputedVariables(el)}
11282
+ mount={pip().pipWindow ? pip().pipWindow.document.body : document.body}
11065
11283
  ><index$f.SubContent
11066
11284
  class={clsx(
11067
11285
  styles().settingsMenu,
@@ -12414,8 +12632,8 @@ var stylesFactory2 = (theme) => {
12414
12632
  gap: ${tokens.size[2]};
12415
12633
  & > button {
12416
12634
  cursor: pointer;
12417
- padding: ${tokens.size[0.5]} ${tokens.size[2]};
12418
- padding-right: ${tokens.size[1.5]};
12635
+ padding: ${tokens.size[0.5]} ${tokens.size[1.5]} ${tokens.size[0.5]}
12636
+ ${tokens.size[2]};
12419
12637
  border-radius: ${tokens.border.radius.sm};
12420
12638
  background-color: ${t2(colors.gray[100], colors.darkGray[400])};
12421
12639
  border: 1px solid ${t2(colors.gray[300], colors.darkGray[200])};