@tanstack/devtools 0.8.1 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import { usePiPWindow, keyboardModifiers, getAllPermutations, TANSTACK_DEVTOOLS, DevtoolsContext, PLUGIN_TITLE_CONTAINER_ID, PLUGIN_CONTAINER_ID, uppercaseFirstLetter, MAX_ACTIVE_PLUGINS } from '../chunk/G64KXXVZ.js';
1
+ import { usePiPWindow, TANSTACK_DEVTOOLS, keyboardModifiers, getAllPermutations, DevtoolsContext, PLUGIN_TITLE_CONTAINER_ID, PLUGIN_CONTAINER_ID, MAX_ACTIVE_PLUGINS, uppercaseFirstLetter } from '../chunk/YGJWPK3G.js';
2
2
  import { delegateEvents, createComponent, Portal, template, use, setAttribute, insert, memo, effect, className, addEventListener, style, classList } from 'solid-js/web';
3
3
  import { createContext, createSignal, createEffect, onCleanup, Show, createMemo, For, useContext, onMount } from 'solid-js';
4
4
  import { createShortcut, useKeyDownList } from '@solid-primitives/keyboard';
@@ -93,6 +93,12 @@ var usePlugins = () => {
93
93
  const toggleActivePlugins = (pluginId) => {
94
94
  setStore((prev) => {
95
95
  const isActive = prev.state.activePlugins.includes(pluginId);
96
+ const currentPlugin = store.plugins?.find(
97
+ (plugin) => plugin.id === pluginId
98
+ );
99
+ if (currentPlugin?.destroy && isActive) {
100
+ currentPlugin.destroy(pluginId);
101
+ }
96
102
  const updatedPlugins = isActive ? prev.state.activePlugins.filter((id) => id !== pluginId) : [...prev.state.activePlugins, pluginId];
97
103
  if (updatedPlugins.length > MAX_ACTIVE_PLUGINS) return prev;
98
104
  return {
@@ -168,6 +174,46 @@ var useDisableTabbing = (isOpen) => {
168
174
  });
169
175
  };
170
176
 
177
+ // src/utils/hotkey.ts
178
+ var normalizeHotkey = (keys) => {
179
+ if (!keys.includes("CtrlOrMeta")) {
180
+ return [keys];
181
+ }
182
+ return [
183
+ keys.map((key) => key === "CtrlOrMeta" ? "Control" : key),
184
+ keys.map((key) => key === "CtrlOrMeta" ? "Meta" : key)
185
+ ];
186
+ };
187
+ var getHotkeyPermutations = (hotkey) => {
188
+ const normalizedHotkeys = normalizeHotkey(hotkey);
189
+ return normalizedHotkeys.flatMap((normalizedHotkey) => {
190
+ const modifiers = normalizedHotkey.filter(
191
+ (key) => keyboardModifiers.includes(key)
192
+ );
193
+ const nonModifiers = normalizedHotkey.filter(
194
+ (key) => !keyboardModifiers.includes(key)
195
+ );
196
+ if (modifiers.length === 0) {
197
+ return [nonModifiers];
198
+ }
199
+ const allModifierCombinations = getAllPermutations(modifiers);
200
+ return allModifierCombinations.map((combo) => [...combo, ...nonModifiers]);
201
+ });
202
+ };
203
+ var isHotkeyCombinationPressed = (keys, hotkey) => {
204
+ const permutations = getHotkeyPermutations(hotkey);
205
+ const pressedKeys = keys.map((key) => key.toUpperCase());
206
+ return permutations.some(
207
+ (combo) => (
208
+ // every key in the combo must be pressed
209
+ combo.every((key) => pressedKeys.includes(String(key).toUpperCase())) && // and no extra keys beyond the combo
210
+ pressedKeys.every(
211
+ (key) => combo.map((k) => String(k).toUpperCase()).includes(key)
212
+ )
213
+ )
214
+ );
215
+ };
216
+
171
217
  // src/styles/tokens.ts
172
218
  var tokens = {
173
219
  colors: {
@@ -898,6 +944,11 @@ var stylesFactory = (theme) => {
898
944
  display: flex;
899
945
  gap: 0.5rem;
900
946
  `,
947
+ settingsStack: css2`
948
+ display: flex;
949
+ flex-direction: column;
950
+ gap: 1rem;
951
+ `,
901
952
  // No Plugins Fallback Styles
902
953
  noPluginsFallback: css2`
903
954
  display: flex;
@@ -1905,29 +1956,99 @@ var ContentPanel = (props) => {
1905
1956
  })();
1906
1957
  };
1907
1958
  delegateEvents(["mousedown"]);
1908
- var _tmpl$6 = /* @__PURE__ */ template(`<div>`);
1909
- var _tmpl$22 = /* @__PURE__ */ template(`<div><div></div>Final shortcut is: `);
1910
- var _tmpl$32 = /* @__PURE__ */ template(`<div><div>`);
1959
+ var _tmpl$6 = /* @__PURE__ */ template(`<div><h4></h4><div></div>Final shortcut is: `);
1960
+ var MODIFIER_DISPLAY_NAMES = {
1961
+ Shift: "Shift",
1962
+ Alt: "Alt",
1963
+ Meta: "Meta",
1964
+ Control: "Control",
1965
+ CtrlOrMeta: "Ctrl Or Meta"
1966
+ };
1967
+ var HotkeyConfig = (props) => {
1968
+ const styles = useStyles();
1969
+ const toggleModifier = (modifier) => {
1970
+ if (props.hotkey.includes(modifier)) {
1971
+ props.onHotkeyChange(props.hotkey.filter((key) => key !== modifier));
1972
+ } else {
1973
+ const existingModifiers = props.hotkey.filter((key) => props.modifiers.includes(key));
1974
+ const otherKeys = props.hotkey.filter((key) => !props.modifiers.includes(key));
1975
+ props.onHotkeyChange([...existingModifiers, modifier, ...otherKeys]);
1976
+ }
1977
+ };
1978
+ const getNonModifierValue = () => {
1979
+ return props.hotkey.filter((key) => !props.modifiers.includes(key)).join("+");
1980
+ };
1981
+ const handleKeyInput = (input) => {
1982
+ const makeModifierArray = (key) => {
1983
+ if (key.length === 1) return [uppercaseFirstLetter(key)];
1984
+ const modifiersArray = [];
1985
+ for (const character of key) {
1986
+ const newLetter = uppercaseFirstLetter(character);
1987
+ if (!modifiersArray.includes(newLetter)) modifiersArray.push(newLetter);
1988
+ }
1989
+ return modifiersArray;
1990
+ };
1991
+ const hotkeyModifiers = props.hotkey.filter((key) => props.modifiers.includes(key));
1992
+ const newKeys = input.split("+").flatMap((key) => makeModifierArray(key)).filter(Boolean);
1993
+ props.onHotkeyChange([...hotkeyModifiers, ...newKeys]);
1994
+ };
1995
+ const getDisplayHotkey = () => {
1996
+ return props.hotkey.join(" + ");
1997
+ };
1998
+ return (() => {
1999
+ var _el$ = _tmpl$6(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.nextSibling;
2000
+ _el$2.style.setProperty("margin", "0");
2001
+ insert(_el$2, () => props.description);
2002
+ insert(_el$3, createComponent(Show, {
2003
+ keyed: true,
2004
+ get when() {
2005
+ return props.hotkey;
2006
+ },
2007
+ get children() {
2008
+ return props.modifiers.map((modifier) => createComponent(Button, {
2009
+ variant: "success",
2010
+ onclick: () => toggleModifier(modifier),
2011
+ get outline() {
2012
+ return !props.hotkey.includes(modifier);
2013
+ },
2014
+ get children() {
2015
+ return MODIFIER_DISPLAY_NAMES[modifier] || modifier;
2016
+ }
2017
+ }));
2018
+ }
2019
+ }));
2020
+ insert(_el$, createComponent(Input, {
2021
+ description: "Use '+' to combine keys (e.g., 'a+b' or 'd'). This will be used with the enabled modifiers from above",
2022
+ placeholder: "a",
2023
+ get value() {
2024
+ return getNonModifierValue();
2025
+ },
2026
+ onChange: handleKeyInput
2027
+ }), _el$4);
2028
+ insert(_el$, getDisplayHotkey, null);
2029
+ effect((_p$) => {
2030
+ var _v$ = styles().settingsGroup, _v$2 = styles().settingsModifiers;
2031
+ _v$ !== _p$.e && className(_el$, _p$.e = _v$);
2032
+ _v$2 !== _p$.t && className(_el$3, _p$.t = _v$2);
2033
+ return _p$;
2034
+ }, {
2035
+ e: void 0,
2036
+ t: void 0
2037
+ });
2038
+ return _el$;
2039
+ })();
2040
+ };
2041
+
2042
+ // src/tabs/settings-tab.tsx
2043
+ var _tmpl$7 = /* @__PURE__ */ template(`<div>`);
2044
+ var _tmpl$22 = /* @__PURE__ */ template(`<div><div>`);
1911
2045
  var SettingsTab = () => {
1912
2046
  const {
1913
2047
  setSettings,
1914
2048
  settings
1915
2049
  } = useDevtoolsSettings();
1916
2050
  const styles = useStyles();
1917
- const hotkey = createMemo(() => settings().openHotkey);
1918
- const modifiers = ["Control", "Alt", "Meta", "Shift"];
1919
- const changeHotkey = (newHotkey) => () => {
1920
- if (hotkey().includes(newHotkey)) {
1921
- return setSettings({
1922
- openHotkey: hotkey().filter((key) => key !== newHotkey)
1923
- });
1924
- }
1925
- const existingModifiers = hotkey().filter((key) => modifiers.includes(key));
1926
- const otherModifiers = hotkey().filter((key) => !modifiers.includes(key));
1927
- setSettings({
1928
- openHotkey: [...existingModifiers, newHotkey, ...otherModifiers]
1929
- });
1930
- };
2051
+ const modifiers = ["CtrlOrMeta", "Alt", "Shift"];
1931
2052
  return createComponent(MainPanel$1, {
1932
2053
  withPadding: true,
1933
2054
  get children() {
@@ -1944,7 +2065,7 @@ var SettingsTab = () => {
1944
2065
  }), createComponent(SectionDescription, {
1945
2066
  children: "Configure general behavior of the devtools panel."
1946
2067
  }), (() => {
1947
- var _el$ = _tmpl$6();
2068
+ var _el$ = _tmpl$7();
1948
2069
  insert(_el$, createComponent(Checkbox, {
1949
2070
  label: "Default open",
1950
2071
  description: "Automatically open the devtools panel when the page loads",
@@ -2009,7 +2130,7 @@ var SettingsTab = () => {
2009
2130
  }), createComponent(SectionDescription, {
2010
2131
  children: "Control when devtools are available based on URL parameters."
2011
2132
  }), (() => {
2012
- var _el$2 = _tmpl$6();
2133
+ var _el$2 = _tmpl$7();
2013
2134
  insert(_el$2, createComponent(Checkbox, {
2014
2135
  label: "Require URL Flag",
2015
2136
  description: "Only show devtools when a specific URL parameter is present",
@@ -2025,7 +2146,7 @@ var SettingsTab = () => {
2025
2146
  return settings().requireUrlFlag;
2026
2147
  },
2027
2148
  get children() {
2028
- var _el$3 = _tmpl$6();
2149
+ var _el$3 = _tmpl$7();
2029
2150
  insert(_el$3, createComponent(Input, {
2030
2151
  label: "URL flag",
2031
2152
  description: "Enter the URL parameter name (e.g., 'debug' for ?debug=true)",
@@ -2058,85 +2179,30 @@ var SettingsTab = () => {
2058
2179
  }), createComponent(SectionDescription, {
2059
2180
  children: "Customize keyboard shortcuts for quick access."
2060
2181
  }), (() => {
2061
- var _el$4 = _tmpl$22(), _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling;
2062
- insert(_el$5, createComponent(Show, {
2063
- keyed: true,
2064
- get when() {
2065
- return hotkey();
2182
+ var _el$4 = _tmpl$7();
2183
+ insert(_el$4, createComponent(HotkeyConfig, {
2184
+ title: "Open/Close Devtools",
2185
+ description: "Hotkey to open/close devtools",
2186
+ get hotkey() {
2187
+ return settings().openHotkey;
2066
2188
  },
2067
- get children() {
2068
- return [createComponent(Button, {
2069
- variant: "success",
2070
- get onclick() {
2071
- return changeHotkey("Shift");
2072
- },
2073
- get outline() {
2074
- return !hotkey().includes("Shift");
2075
- },
2076
- children: "Shift"
2077
- }), createComponent(Button, {
2078
- variant: "success",
2079
- get onclick() {
2080
- return changeHotkey("Alt");
2081
- },
2082
- get outline() {
2083
- return !hotkey().includes("Alt");
2084
- },
2085
- children: "Alt"
2086
- }), createComponent(Button, {
2087
- variant: "success",
2088
- get onclick() {
2089
- return changeHotkey("Meta");
2090
- },
2091
- get outline() {
2092
- return !hotkey().includes("Meta");
2093
- },
2094
- children: "Meta"
2095
- }), createComponent(Button, {
2096
- variant: "success",
2097
- get onclick() {
2098
- return changeHotkey("Control");
2099
- },
2100
- get outline() {
2101
- return !hotkey().includes("Control");
2102
- },
2103
- children: "Control"
2104
- })];
2105
- }
2106
- }));
2107
- insert(_el$4, createComponent(Input, {
2108
- label: "Hotkey to open/close devtools",
2109
- description: "Use '+' to combine keys (e.g., 'a+b' or 'd'). This will be used with the enabled modifiers from above",
2110
- placeholder: "a",
2111
- get value() {
2112
- return hotkey().filter((key) => !["Shift", "Meta", "Alt", "Ctrl"].includes(key)).join("+");
2189
+ modifiers,
2190
+ onHotkeyChange: (hotkey) => setSettings({
2191
+ openHotkey: hotkey
2192
+ })
2193
+ }), null);
2194
+ insert(_el$4, createComponent(HotkeyConfig, {
2195
+ title: "Source Inspector",
2196
+ description: "Hotkey to open source inspector",
2197
+ get hotkey() {
2198
+ return settings().inspectHotkey;
2113
2199
  },
2114
- onChange: (e) => {
2115
- const makeModifierArray = (key) => {
2116
- if (key.length === 1) return [uppercaseFirstLetter(key)];
2117
- const modifiers3 = [];
2118
- for (const character of key) {
2119
- const newLetter = uppercaseFirstLetter(character);
2120
- if (!modifiers3.includes(newLetter)) modifiers3.push(newLetter);
2121
- }
2122
- return modifiers3;
2123
- };
2124
- const modifiers2 = e.split("+").flatMap((key) => makeModifierArray(key)).filter(Boolean);
2125
- return setSettings({
2126
- openHotkey: [...hotkey().filter((key) => ["Shift", "Meta", "Alt", "Ctrl"].includes(key)), ...modifiers2]
2127
- });
2128
- }
2129
- }), _el$6);
2130
- insert(_el$4, () => hotkey().join(" + "), null);
2131
- effect((_p$) => {
2132
- var _v$ = styles().settingsGroup, _v$2 = styles().settingsModifiers;
2133
- _v$ !== _p$.e && className(_el$4, _p$.e = _v$);
2134
- _v$2 !== _p$.t && className(_el$5, _p$.t = _v$2);
2135
- return _p$;
2136
- }, {
2137
- e: void 0,
2138
- t: void 0
2139
- });
2200
+ modifiers,
2201
+ onHotkeyChange: (hotkey) => setSettings({
2202
+ inspectHotkey: hotkey
2203
+ })
2204
+ }), null);
2205
+ effect(() => className(_el$4, styles().settingsStack));
2140
2206
  return _el$4;
2141
2207
  })()];
2142
2208
  }
@@ -2153,8 +2219,8 @@ var SettingsTab = () => {
2153
2219
  }), createComponent(SectionDescription, {
2154
2220
  children: "Adjust the position of the trigger button and devtools panel."
2155
2221
  }), (() => {
2156
- var _el$7 = _tmpl$32(), _el$8 = _el$7.firstChild;
2157
- insert(_el$8, createComponent(Select, {
2222
+ var _el$5 = _tmpl$22(), _el$6 = _el$5.firstChild;
2223
+ insert(_el$6, createComponent(Select, {
2158
2224
  label: "Trigger Position",
2159
2225
  options: [{
2160
2226
  label: "Bottom Right",
@@ -2182,7 +2248,7 @@ var SettingsTab = () => {
2182
2248
  position: value
2183
2249
  })
2184
2250
  }), null);
2185
- insert(_el$8, createComponent(Select, {
2251
+ insert(_el$6, createComponent(Select, {
2186
2252
  label: "Panel Position",
2187
2253
  get value() {
2188
2254
  return settings().panelLocation;
@@ -2199,15 +2265,15 @@ var SettingsTab = () => {
2199
2265
  })
2200
2266
  }), null);
2201
2267
  effect((_p$) => {
2202
- var _v$3 = styles().settingsGroup, _v$4 = styles().settingRow;
2203
- _v$3 !== _p$.e && className(_el$7, _p$.e = _v$3);
2204
- _v$4 !== _p$.t && className(_el$8, _p$.t = _v$4);
2268
+ var _v$ = styles().settingsGroup, _v$2 = styles().settingRow;
2269
+ _v$ !== _p$.e && className(_el$5, _p$.e = _v$);
2270
+ _v$2 !== _p$.t && className(_el$6, _p$.t = _v$2);
2205
2271
  return _p$;
2206
2272
  }, {
2207
2273
  e: void 0,
2208
2274
  t: void 0
2209
2275
  });
2210
- return _el$7;
2276
+ return _el$5;
2211
2277
  })()];
2212
2278
  }
2213
2279
  })];
@@ -2291,14 +2357,14 @@ var getBadgeText = (card) => {
2291
2357
  };
2292
2358
 
2293
2359
  // src/tabs/marketplace/plugin-card.tsx
2294
- var _tmpl$7 = /* @__PURE__ */ template(`<div>New`);
2360
+ var _tmpl$8 = /* @__PURE__ */ template(`<div>New`);
2295
2361
  var _tmpl$23 = /* @__PURE__ */ template(`<img>`);
2296
- var _tmpl$33 = /* @__PURE__ */ template(`<span>\u2713 v<!> \u2022 Min v`);
2362
+ var _tmpl$32 = /* @__PURE__ */ template(`<span>\u2713 v<!> \u2022 Min v`);
2297
2363
  var _tmpl$42 = /* @__PURE__ */ template(`<p>`);
2298
2364
  var _tmpl$52 = /* @__PURE__ */ template(`<a target=_blank rel="noopener noreferrer">Documentation `);
2299
2365
  var _tmpl$62 = /* @__PURE__ */ template(`<div>`);
2300
2366
  var _tmpl$72 = /* @__PURE__ */ template(`<div><span></span><div></div><div><h3></h3><p></p><p>`);
2301
- var _tmpl$8 = /* @__PURE__ */ template(`<span>\u26A0\uFE0F v<!> \u2022 Requires v<!>+`);
2367
+ var _tmpl$82 = /* @__PURE__ */ template(`<span>\u26A0\uFE0F v<!> \u2022 Requires v<!>+`);
2302
2368
  var _tmpl$9 = /* @__PURE__ */ template(`<span>`);
2303
2369
  var _tmpl$0 = /* @__PURE__ */ template(`<span>Installing...`);
2304
2370
  var _tmpl$1 = /* @__PURE__ */ template(`<span>Installed!`);
@@ -2315,7 +2381,7 @@ var PluginCardComponent = (props) => {
2315
2381
  return card.metadata?.isNew;
2316
2382
  },
2317
2383
  get children() {
2318
- var _el$2 = _tmpl$7();
2384
+ var _el$2 = _tmpl$8();
2319
2385
  effect(() => className(_el$2, styles().pluginMarketplaceNewBanner));
2320
2386
  return _el$2;
2321
2387
  }
@@ -2359,7 +2425,7 @@ var PluginCardComponent = (props) => {
2359
2425
  },
2360
2426
  get fallback() {
2361
2427
  return (() => {
2362
- var _el$16 = _tmpl$8(), _el$17 = _el$16.firstChild, _el$20 = _el$17.nextSibling, _el$18 = _el$20.nextSibling, _el$21 = _el$18.nextSibling; _el$21.nextSibling;
2428
+ var _el$16 = _tmpl$82(), _el$17 = _el$16.firstChild, _el$20 = _el$17.nextSibling, _el$18 = _el$20.nextSibling, _el$21 = _el$18.nextSibling; _el$21.nextSibling;
2363
2429
  insert(_el$16, () => card.versionInfo?.current, _el$20);
2364
2430
  insert(_el$16, () => card.versionInfo?.required, _el$21);
2365
2431
  effect(() => className(_el$16, styles().pluginMarketplaceCardVersionUnsatisfied));
@@ -2367,7 +2433,7 @@ var PluginCardComponent = (props) => {
2367
2433
  })();
2368
2434
  },
2369
2435
  get children() {
2370
- var _el$1 = _tmpl$33(), _el$10 = _el$1.firstChild, _el$12 = _el$10.nextSibling; _el$12.nextSibling;
2436
+ var _el$1 = _tmpl$32(), _el$10 = _el$1.firstChild, _el$12 = _el$10.nextSibling; _el$12.nextSibling;
2371
2437
  insert(_el$1, () => card.versionInfo?.current, _el$12);
2372
2438
  insert(_el$1, () => card.versionInfo?.required, null);
2373
2439
  effect(() => className(_el$1, styles().pluginMarketplaceCardVersionSatisfied));
@@ -2522,7 +2588,7 @@ var PluginCardComponent = (props) => {
2522
2588
  // src/tabs/marketplace/plugin-section.tsx
2523
2589
  var _tmpl$10 = /* @__PURE__ */ template(`<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=currentColor><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z">`);
2524
2590
  var _tmpl$24 = /* @__PURE__ */ template(`<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><rect x=2 y=4 width=20 height=16 rx=2></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7">`);
2525
- var _tmpl$34 = /* @__PURE__ */ template(`<div><div><h4><span></span>Want to be featured here?</h4><p>If you've built a plugin for TanStack Devtools and would like to showcase it in the featured section, we'd love to hear from you! Reach out to us to discuss partnership opportunities.</p><a href="mailto:partners+devtools@tanstack.com?subject=Featured%20Plugin%20Partnership%20Inquiry"><span></span>Contact Us`);
2591
+ var _tmpl$33 = /* @__PURE__ */ template(`<div><div><h4><span></span>Want to be featured here?</h4><p>If you've built a plugin for TanStack Devtools and would like to showcase it in the featured section, we'd love to hear from you! Reach out to us to discuss partnership opportunities.</p><a href="mailto:partners+devtools@tanstack.com?subject=Featured%20Plugin%20Partnership%20Inquiry"><span></span>Contact Us`);
2526
2592
  var _tmpl$43 = /* @__PURE__ */ template(`<div>`);
2527
2593
  var _tmpl$53 = /* @__PURE__ */ template(`<div><div><div><div></div><h3>`);
2528
2594
  var StarIcon = () => _tmpl$10();
@@ -2544,7 +2610,7 @@ var PluginSectionComponent = (props) => {
2544
2610
  return props.section.id === "featured";
2545
2611
  },
2546
2612
  get children() {
2547
- var _el$8 = _tmpl$34(), _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.firstChild, _el$10 = _el$0.nextSibling, _el$11 = _el$10.nextSibling, _el$12 = _el$11.firstChild;
2613
+ var _el$8 = _tmpl$33(), _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$1 = _el$0.firstChild, _el$10 = _el$0.nextSibling, _el$11 = _el$10.nextSibling, _el$12 = _el$11.firstChild;
2548
2614
  insert(_el$1, createComponent(StarIcon, {}));
2549
2615
  insert(_el$12, createComponent(MailIcon, {}));
2550
2616
  effect((_p$) => {
@@ -3375,7 +3441,7 @@ var PluginMarketplace = () => {
3375
3441
  // src/tabs/plugins-tab.tsx
3376
3442
  var _tmpl$15 = /* @__PURE__ */ template(`<div><div><div><div></div><div><h3>Add More`);
3377
3443
  var _tmpl$27 = /* @__PURE__ */ template(`<div><h3>`);
3378
- var _tmpl$35 = /* @__PURE__ */ template(`<div>`);
3444
+ var _tmpl$34 = /* @__PURE__ */ template(`<div>`);
3379
3445
  var PluginsTab = () => {
3380
3446
  const {
3381
3447
  plugins,
@@ -3472,7 +3538,7 @@ var PluginsTab = () => {
3472
3538
  return activePlugins();
3473
3539
  },
3474
3540
  children: (pluginId) => (() => {
3475
- var _el$8 = _tmpl$35();
3541
+ var _el$8 = _tmpl$34();
3476
3542
  use((el) => {
3477
3543
  setPluginRefs((prev) => {
3478
3544
  const updated = new Map(prev);
@@ -3578,7 +3644,7 @@ function useHeadChanges(onChange, opts = {}) {
3578
3644
  // src/tabs/seo-tab.tsx
3579
3645
  var _tmpl$16 = /* @__PURE__ */ template(`<div><div> Preview</div><div></div><div></div><div>`);
3580
3646
  var _tmpl$28 = /* @__PURE__ */ template(`<img alt=Preview>`);
3581
- var _tmpl$36 = /* @__PURE__ */ template(`<div>No Image`);
3647
+ var _tmpl$35 = /* @__PURE__ */ template(`<div>No Image`);
3582
3648
  var _tmpl$44 = /* @__PURE__ */ template(`<div>`);
3583
3649
  var _tmpl$54 = /* @__PURE__ */ template(`<div><strong>Missing tags for <!>:</strong><ul>`);
3584
3650
  var _tmpl$63 = /* @__PURE__ */ template(`<li>`);
@@ -3724,7 +3790,7 @@ function SocialPreview(props) {
3724
3790
  });
3725
3791
  return _el$7;
3726
3792
  })() : (() => {
3727
- var _el$8 = _tmpl$36();
3793
+ var _el$8 = _tmpl$35();
3728
3794
  _el$8.style.setProperty("background", "#222");
3729
3795
  _el$8.style.setProperty("color", "#888");
3730
3796
  _el$8.style.setProperty("display", "flex");
@@ -3887,7 +3953,7 @@ var tabs = [{
3887
3953
  // src/components/tabs.tsx
3888
3954
  var _tmpl$17 = /* @__PURE__ */ template(`<div>`);
3889
3955
  var _tmpl$29 = /* @__PURE__ */ template(`<button type=button>`);
3890
- var _tmpl$37 = /* @__PURE__ */ template(`<div><button type=button></button><button type=button>`);
3956
+ var _tmpl$36 = /* @__PURE__ */ template(`<div><button type=button></button><button type=button>`);
3891
3957
  var Tabs = (props) => {
3892
3958
  const styles = useStyles();
3893
3959
  const {
@@ -3926,7 +3992,7 @@ var Tabs = (props) => {
3926
3992
  insert(_el$, (() => {
3927
3993
  var _c$ = memo(() => pipWindow().pipWindow !== null);
3928
3994
  return () => _c$() ? null : (() => {
3929
- var _el$3 = _tmpl$37(), _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling;
3995
+ var _el$3 = _tmpl$36(), _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling;
3930
3996
  _el$3.style.setProperty("margin-top", "auto");
3931
3997
  _el$4.$$click = handleDetachment;
3932
3998
  insert(_el$4, createComponent(PiP, {}));
@@ -3965,6 +4031,9 @@ var TabContent = () => {
3965
4031
  };
3966
4032
  var _tmpl$19 = /* @__PURE__ */ template(`<div>`);
3967
4033
  var SourceInspector = () => {
4034
+ const {
4035
+ settings
4036
+ } = useDevtoolsSettings();
3968
4037
  const highlightStateInit = () => ({
3969
4038
  element: null,
3970
4039
  bounding: {
@@ -3993,11 +4062,7 @@ var SourceInspector = () => {
3993
4062
  });
3994
4063
  const downList = useKeyDownList();
3995
4064
  const isHighlightingKeysHeld = createMemo(() => {
3996
- const keys = downList();
3997
- const isShiftHeld = keys.includes("SHIFT");
3998
- const isCtrlHeld = keys.includes("CONTROL");
3999
- const isMetaHeld = keys.includes("META");
4000
- return isShiftHeld && (isCtrlHeld || isMetaHeld);
4065
+ return isHotkeyCombinationPressed(downList(), settings().inspectHotkey);
4001
4066
  });
4002
4067
  createEffect(() => {
4003
4068
  if (!isHighlightingKeysHeld()) {
@@ -4233,11 +4298,8 @@ function DevTools() {
4233
4298
  }
4234
4299
  });
4235
4300
  createEffect(() => {
4236
- const modifiers = settings().openHotkey.filter((key) => keyboardModifiers.includes(key));
4237
- const nonModifiers = settings().openHotkey.filter((key) => !keyboardModifiers.includes(key));
4238
- const allModifierCombinations = getAllPermutations(modifiers);
4239
- for (const combination of allModifierCombinations) {
4240
- const permutation = [...combination, ...nonModifiers];
4301
+ const permutations = getHotkeyPermutations(settings().openHotkey);
4302
+ for (const permutation of permutations) {
4241
4303
  createShortcut(permutation, () => {
4242
4304
  toggleOpen();
4243
4305
  });
package/dist/index.d.ts CHANGED
@@ -23,8 +23,9 @@ declare const tabs: readonly [{
23
23
  }];
24
24
  type TabName = (typeof tabs)[number]['id'];
25
25
 
26
- type ModifierKey = 'Alt' | 'Control' | 'Meta' | 'Shift';
26
+ type ModifierKey = 'Alt' | 'Control' | 'Meta' | 'Shift' | 'CtrlOrMeta';
27
27
  type KeyboardKey = ModifierKey | (string & {});
28
+
28
29
  type TriggerPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'middle-left' | 'middle-right';
29
30
  type TriggerProps = {
30
31
  theme: 'light' | 'dark';
@@ -53,9 +54,14 @@ type DevtoolsStore = {
53
54
  panelLocation: 'top' | 'bottom';
54
55
  /**
55
56
  * The hotkey to open the dev tools
56
- * @default "shift+a"
57
+ * @default ["Shift", "A"]
57
58
  */
58
59
  openHotkey: Array<KeyboardKey>;
60
+ /**
61
+ * The hotkey to open the source inspector
62
+ * @default ["Shift", "CtrlOrMeta"]
63
+ */
64
+ inspectHotkey: Array<KeyboardKey>;
59
65
  /**
60
66
  * Whether to require the URL flag to open the dev tools
61
67
  * @default false
@@ -144,6 +150,7 @@ interface TanStackDevtoolsPlugin {
144
150
  * ```
145
151
  */
146
152
  render: (el: HTMLDivElement, theme: DevtoolsStore['settings']['theme']) => void;
153
+ destroy?: (pluginId: string) => void;
147
154
  }
148
155
  type TanStackDevtoolsConfig = DevtoolsStore['settings'];
149
156
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { initialState, DevtoolsProvider, PiPProvider } from './chunk/G64KXXVZ.js';
2
- export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/G64KXXVZ.js';
1
+ import { initialState, DevtoolsProvider, PiPProvider } from './chunk/YGJWPK3G.js';
2
+ export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/YGJWPK3G.js';
3
3
  import { render, createComponent, Portal } from 'solid-js/web';
4
4
  import { lazy } from 'solid-js';
5
5
  import { ClientEventBus } from '@tanstack/devtools-event-bus/client';
@@ -30,7 +30,7 @@ var TanStackDevtoolsCore = class {
30
30
  const mountTo = el;
31
31
  const dispose = render(() => {
32
32
  const _self$ = this;
33
- this.#Component = lazy(() => import('./devtools/OLELRPKB.js'));
33
+ this.#Component = lazy(() => import('./devtools/LWN3DL7E.js'));
34
34
  const Devtools = this.#Component;
35
35
  this.#eventBus = new ClientEventBus(this.#eventBusConfig);
36
36
  this.#eventBus.start();
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
- import { initialState } from './chunk/G64KXXVZ.js';
2
- export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/G64KXXVZ.js';
1
+ import { initialState } from './chunk/YGJWPK3G.js';
2
+ export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/YGJWPK3G.js';
3
3
  import 'solid-js/web';
4
4
  import 'solid-js';
5
5
  import '@tanstack/devtools-event-bus/client';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/devtools",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "description": "TanStack Devtools is a set of tools for building advanced devtools for your application.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -55,8 +55,8 @@
55
55
  "clsx": "^2.1.1",
56
56
  "goober": "^2.1.16",
57
57
  "solid-js": "^1.9.9",
58
- "@tanstack/devtools-client": "0.0.4",
59
58
  "@tanstack/devtools-event-bus": "0.3.3",
59
+ "@tanstack/devtools-client": "0.0.4",
60
60
  "@tanstack/devtools-ui": "0.4.4"
61
61
  },
62
62
  "peerDependencies": {
@@ -4,7 +4,11 @@ import { createElementSize } from '@solid-primitives/resize-observer'
4
4
  import { useKeyDownList } from '@solid-primitives/keyboard'
5
5
  import { createEventListener } from '@solid-primitives/event-listener'
6
6
 
7
+ import { useDevtoolsSettings } from '../context/use-devtools-context'
8
+ import { isHotkeyCombinationPressed } from '../utils/hotkey'
9
+
7
10
  export const SourceInspector = () => {
11
+ const { settings } = useDevtoolsSettings()
8
12
  const highlightStateInit = () => ({
9
13
  element: null as HTMLElement | null,
10
14
  bounding: { width: 0, height: 0, left: 0, top: 0 },
@@ -25,12 +29,9 @@ export const SourceInspector = () => {
25
29
  })
26
30
 
27
31
  const downList = useKeyDownList()
32
+
28
33
  const isHighlightingKeysHeld = createMemo(() => {
29
- const keys = downList()
30
- const isShiftHeld = keys.includes('SHIFT')
31
- const isCtrlHeld = keys.includes('CONTROL')
32
- const isMetaHeld = keys.includes('META')
33
- return isShiftHeld && (isCtrlHeld || isMetaHeld)
34
+ return isHotkeyCombinationPressed(downList(), settings().inspectHotkey)
34
35
  })
35
36
 
36
37
  createEffect(() => {
@@ -73,6 +73,8 @@ export interface TanStackDevtoolsPlugin {
73
73
  el: HTMLDivElement,
74
74
  theme: DevtoolsStore['settings']['theme'],
75
75
  ) => void
76
+
77
+ destroy?: (pluginId: string) => void
76
78
  }
77
79
  export const DevtoolsContext = createContext<{
78
80
  store: DevtoolsStore