@tanstack/devtools 0.0.0 → 0.1.1

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.
Files changed (127) hide show
  1. package/README.md +41 -0
  2. package/dist/cjs/components/checkbox.cjs +55 -0
  3. package/dist/cjs/components/checkbox.cjs.map +1 -0
  4. package/dist/cjs/components/checkbox.d.cts +8 -0
  5. package/dist/cjs/components/content-panel.cjs +5 -1
  6. package/dist/cjs/components/content-panel.cjs.map +1 -1
  7. package/dist/cjs/components/input.cjs +57 -0
  8. package/dist/cjs/components/input.cjs.map +1 -0
  9. package/dist/cjs/components/input.d.cts +10 -0
  10. package/dist/cjs/components/logo.cjs.map +1 -1
  11. package/dist/cjs/components/main-panel.cjs +4 -1
  12. package/dist/cjs/components/main-panel.cjs.map +1 -1
  13. package/dist/cjs/components/main-panel.d.cts +1 -2
  14. package/dist/cjs/components/select.cjs +59 -0
  15. package/dist/cjs/components/select.cjs.map +1 -0
  16. package/dist/cjs/components/select.d.cts +13 -0
  17. package/dist/cjs/components/tab-content.cjs +2 -4
  18. package/dist/cjs/components/tab-content.cjs.map +1 -1
  19. package/dist/cjs/components/tabs.cjs.map +1 -1
  20. package/dist/cjs/components/trigger.cjs +1 -1
  21. package/dist/cjs/components/trigger.cjs.map +1 -1
  22. package/dist/cjs/constants.cjs +7 -0
  23. package/dist/cjs/constants.cjs.map +1 -0
  24. package/dist/cjs/constants.d.cts +2 -0
  25. package/dist/cjs/context/devtools-context.cjs +16 -1
  26. package/dist/cjs/context/devtools-context.cjs.map +1 -1
  27. package/dist/cjs/context/devtools-context.d.cts +49 -7
  28. package/dist/cjs/context/devtools-store.cjs.map +1 -1
  29. package/dist/cjs/context/devtools-store.d.cts +3 -3
  30. package/dist/cjs/context/use-devtools-context.cjs +2 -2
  31. package/dist/cjs/context/use-devtools-context.cjs.map +1 -1
  32. package/dist/cjs/context/use-devtools-context.d.cts +4 -5
  33. package/dist/cjs/core.cjs +29 -43
  34. package/dist/cjs/core.cjs.map +1 -1
  35. package/dist/cjs/core.d.cts +31 -8
  36. package/dist/cjs/devtools.cjs +40 -29
  37. package/dist/cjs/devtools.cjs.map +1 -1
  38. package/dist/cjs/hooks/use-disable-tabbing.cjs.map +1 -1
  39. package/dist/cjs/index.cjs +4 -1
  40. package/dist/cjs/index.cjs.map +1 -1
  41. package/dist/cjs/index.d.cts +4 -3
  42. package/dist/cjs/styles/tokens.cjs +7 -2
  43. package/dist/cjs/styles/tokens.cjs.map +1 -1
  44. package/dist/cjs/styles/use-styles.cjs +251 -11
  45. package/dist/cjs/styles/use-styles.cjs.map +1 -1
  46. package/dist/cjs/styles/use-styles.d.cts +29 -5
  47. package/dist/cjs/tabs/index.cjs.map +1 -1
  48. package/dist/cjs/tabs/plugins-tab.cjs +8 -12
  49. package/dist/cjs/tabs/plugins-tab.cjs.map +1 -1
  50. package/dist/cjs/tabs/settings-tab.cjs +172 -2
  51. package/dist/cjs/tabs/settings-tab.cjs.map +1 -1
  52. package/dist/cjs/utils/sanitize.cjs +2 -0
  53. package/dist/cjs/utils/sanitize.cjs.map +1 -1
  54. package/dist/cjs/utils/sanitize.d.cts +1 -0
  55. package/dist/cjs/utils/storage.cjs.map +1 -1
  56. package/dist/esm/components/checkbox.d.ts +8 -0
  57. package/dist/esm/components/checkbox.js +55 -0
  58. package/dist/esm/components/checkbox.js.map +1 -0
  59. package/dist/esm/components/content-panel.js +5 -1
  60. package/dist/esm/components/content-panel.js.map +1 -1
  61. package/dist/esm/components/input.d.ts +10 -0
  62. package/dist/esm/components/input.js +57 -0
  63. package/dist/esm/components/input.js.map +1 -0
  64. package/dist/esm/components/logo.js.map +1 -1
  65. package/dist/esm/components/main-panel.d.ts +1 -2
  66. package/dist/esm/components/main-panel.js +5 -2
  67. package/dist/esm/components/main-panel.js.map +1 -1
  68. package/dist/esm/components/select.d.ts +13 -0
  69. package/dist/esm/components/select.js +59 -0
  70. package/dist/esm/components/select.js.map +1 -0
  71. package/dist/esm/components/tab-content.js +2 -4
  72. package/dist/esm/components/tab-content.js.map +1 -1
  73. package/dist/esm/components/tabs.js.map +1 -1
  74. package/dist/esm/components/trigger.js +1 -1
  75. package/dist/esm/components/trigger.js.map +1 -1
  76. package/dist/esm/constants.d.ts +2 -0
  77. package/dist/esm/constants.js +7 -0
  78. package/dist/esm/constants.js.map +1 -0
  79. package/dist/esm/context/devtools-context.d.ts +49 -7
  80. package/dist/esm/context/devtools-context.js +16 -1
  81. package/dist/esm/context/devtools-context.js.map +1 -1
  82. package/dist/esm/context/devtools-store.d.ts +3 -3
  83. package/dist/esm/context/devtools-store.js.map +1 -1
  84. package/dist/esm/context/use-devtools-context.d.ts +4 -5
  85. package/dist/esm/context/use-devtools-context.js +2 -2
  86. package/dist/esm/context/use-devtools-context.js.map +1 -1
  87. package/dist/esm/core.d.ts +31 -8
  88. package/dist/esm/core.js +29 -43
  89. package/dist/esm/core.js.map +1 -1
  90. package/dist/esm/devtools.js +42 -31
  91. package/dist/esm/devtools.js.map +1 -1
  92. package/dist/esm/hooks/use-disable-tabbing.js.map +1 -1
  93. package/dist/esm/index.d.ts +4 -3
  94. package/dist/esm/index.js +5 -2
  95. package/dist/esm/index.js.map +1 -1
  96. package/dist/esm/styles/tokens.js +7 -2
  97. package/dist/esm/styles/tokens.js.map +1 -1
  98. package/dist/esm/styles/use-styles.d.ts +29 -5
  99. package/dist/esm/styles/use-styles.js +251 -11
  100. package/dist/esm/styles/use-styles.js.map +1 -1
  101. package/dist/esm/tabs/index.js.map +1 -1
  102. package/dist/esm/tabs/plugins-tab.js +9 -13
  103. package/dist/esm/tabs/plugins-tab.js.map +1 -1
  104. package/dist/esm/tabs/settings-tab.js +173 -3
  105. package/dist/esm/tabs/settings-tab.js.map +1 -1
  106. package/dist/esm/utils/sanitize.d.ts +1 -0
  107. package/dist/esm/utils/sanitize.js +3 -1
  108. package/dist/esm/utils/sanitize.js.map +1 -1
  109. package/dist/esm/utils/storage.js.map +1 -1
  110. package/package.json +7 -9
  111. package/src/components/checkbox.tsx +43 -0
  112. package/src/components/content-panel.tsx +3 -1
  113. package/src/components/input.tsx +42 -0
  114. package/src/components/main-panel.tsx +4 -4
  115. package/src/components/select.tsx +50 -0
  116. package/src/components/trigger.tsx +1 -1
  117. package/src/constants.ts +2 -0
  118. package/src/context/devtools-context.tsx +72 -11
  119. package/src/context/devtools-store.ts +3 -3
  120. package/src/context/use-devtools-context.ts +2 -3
  121. package/src/core.tsx +42 -20
  122. package/src/devtools.tsx +34 -18
  123. package/src/index.ts +7 -3
  124. package/src/styles/use-styles.ts +257 -13
  125. package/src/tabs/plugins-tab.tsx +11 -5
  126. package/src/tabs/settings-tab.tsx +217 -1
  127. package/src/utils/sanitize.ts +3 -0
@@ -1 +1 @@
1
- {"version":3,"file":"settings-tab.js","sources":["../../../src/tabs/settings-tab.tsx"],"sourcesContent":["export const SettingsTab = () => {\n return <div>Settings</div>\n}\n"],"names":["SettingsTab","_tmpl$"],"mappings":";;AAAO,MAAMA,cAAcA,MAAM;AAC/B,SAAAC,OAAA;AACF;"}
1
+ {"version":3,"file":"settings-tab.js","sources":["../../../src/tabs/settings-tab.tsx"],"sourcesContent":["import { Show } from 'solid-js'\nimport { Input } from '../components/input'\nimport { Select } from '../components/select'\nimport { useDevtoolsSettings } from '../context/use-devtools-context'\nimport { uppercaseFirstLetter } from '../utils/sanitize'\nimport { Checkbox } from '../components/checkbox'\nimport { useStyles } from '../styles/use-styles'\n\nexport const SettingsTab = () => {\n const { setSettings, settings } = useDevtoolsSettings()\n const styles = useStyles()\n\n return (\n <div class={styles().settingsContainer}>\n {/* General Settings */}\n <div class={styles().settingsSection}>\n <h3 class={styles().sectionTitle}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class={styles().sectionIcon}\n >\n <path d=\"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n General\n </h3>\n <p class={styles().sectionDescription}>\n Configure general behavior of the devtools panel.\n </p>\n <div class={styles().settingsGroup}>\n <Checkbox\n label=\"Default open\"\n description=\"Automatically open the devtools panel when the page loads\"\n onChange={() =>\n setSettings({ defaultOpen: !settings().defaultOpen })\n }\n checked={settings().defaultOpen}\n />\n <Checkbox\n label=\"Hide trigger until hovered\"\n description=\"Keep the devtools trigger button hidden until you hover over its area\"\n onChange={() =>\n setSettings({ hideUntilHover: !settings().hideUntilHover })\n }\n checked={settings().hideUntilHover}\n />\n </div>\n </div>\n\n {/* URL Flag Settings */}\n <div class={styles().settingsSection}>\n <h3 class={styles().sectionTitle}>\n <svg\n class={styles().sectionIcon}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M9 17H7A5 5 0 0 1 7 7h2\" />\n <path d=\"M15 7h2a5 5 0 1 1 0 10h-2\" />\n <line x1=\"8\" x2=\"16\" y1=\"12\" y2=\"12\" />\n </svg>\n URL Configuration\n </h3>\n <p class={styles().sectionDescription}>\n Control when devtools are available based on URL parameters.\n </p>\n <div class={styles().settingsGroup}>\n <Checkbox\n label=\"Require URL Flag\"\n description=\"Only show devtools when a specific URL parameter is present\"\n checked={settings().requireUrlFlag}\n onChange={(checked) =>\n setSettings({\n requireUrlFlag: checked,\n })\n }\n />\n <Show when={settings().requireUrlFlag}>\n <div class={styles().conditionalSetting}>\n <Input\n label=\"URL flag\"\n description=\"Enter the URL parameter name (e.g., 'debug' for ?debug=true)\"\n placeholder=\"debug\"\n value={settings().urlFlag}\n onChange={(e) =>\n setSettings({\n urlFlag: e,\n })\n }\n />\n </div>\n </Show>\n </div>\n </div>\n\n {/* Keyboard Settings */}\n <div class={styles().settingsSection}>\n <h3 class={styles().sectionTitle}>\n <svg\n class={styles().sectionIcon}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M10 8h.01\" />\n <path d=\"M12 12h.01\" />\n <path d=\"M14 8h.01\" />\n <path d=\"M16 12h.01\" />\n <path d=\"M18 8h.01\" />\n <path d=\"M6 8h.01\" />\n <path d=\"M7 16h10\" />\n <path d=\"M8 12h.01\" />\n <rect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\" />\n </svg>\n Keyboard\n </h3>\n <p class={styles().sectionDescription}>\n Customize keyboard shortcuts for quick access.\n </p>\n <div class={styles().settingsGroup}>\n <Input\n label=\"Hotkey to open/close devtools\"\n description=\"Use '+' to combine keys (e.g., 'Ctrl+Shift+D' or 'Alt+D')\"\n placeholder=\"Ctrl+Shift+D\"\n value={settings().openHotkey.join('+')}\n onChange={(e) =>\n setSettings({\n openHotkey: e\n .split('+')\n .map((key) => uppercaseFirstLetter(key))\n .filter(Boolean),\n })\n }\n />\n </div>\n </div>\n\n {/* Position Settings */}\n <div class={styles().settingsSection}>\n <h3 class={styles().sectionTitle}>\n <svg\n class={styles().sectionIcon}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n </svg>\n Position\n </h3>\n <p class={styles().sectionDescription}>\n Adjust the position of the trigger button and devtools panel.\n </p>\n <div class={styles().settingsGroup}>\n <div class={styles().settingRow}>\n <Select\n label=\"Trigger Position\"\n options={[\n { label: 'Bottom Right', value: 'bottom-right' },\n { label: 'Bottom Left', value: 'bottom-left' },\n { label: 'Top Right', value: 'top-right' },\n { label: 'Top Left', value: 'top-left' },\n { label: 'Middle Right', value: 'middle-right' },\n { label: 'Middle Left', value: 'middle-left' },\n ]}\n value={settings().position}\n onChange={(value) =>\n setSettings({\n position: value,\n })\n }\n />\n <Select\n label=\"Panel Position\"\n value={settings().panelLocation}\n options={[\n { label: 'Top', value: 'top' },\n { label: 'Bottom', value: 'bottom' },\n ]}\n onChange={(value) =>\n setSettings({\n panelLocation: value,\n })\n }\n />\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"names":["SettingsTab","setSettings","settings","useDevtoolsSettings","styles","useStyles","_el$","_tmpl$2","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$7","_el$8","_el$9","_el$10","_el$11","_el$13","_el$14","_el$15","_el$16","_el$17","_el$18","_el$19","_el$20","_el$21","_el$22","_el$23","_$insert","_$createComponent","Checkbox","label","description","onChange","defaultOpen","checked","hideUntilHover","requireUrlFlag","Show","when","children","_el$12","_tmpl$","Input","placeholder","value","urlFlag","e","_$effect","_$className","conditionalSetting","openHotkey","join","split","map","key","uppercaseFirstLetter","filter","Boolean","Select","options","position","panelLocation","_p$","_v$","settingsContainer","_v$2","settingsSection","_v$3","sectionTitle","_v$4","sectionIcon","_v$5","sectionDescription","_v$6","settingsGroup","_v$7","_v$8","_v$9","_v$10","_v$11","_v$12","_v$13","_v$14","_v$15","_v$16","_v$17","_v$18","_v$19","_v$20","_v$21","_v$22","settingRow","t","a","o","_$setAttribute","i","n","s","h","r","d","l","u","c","w","m","f","y","g","p","b","T","A","undefined"],"mappings":"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"}
@@ -1 +1,2 @@
1
1
  export declare const tryParseJson: <T>(json: string | null) => T | undefined;
2
+ export declare const uppercaseFirstLetter: (value: string) => string;
@@ -6,7 +6,9 @@ const tryParseJson = (json) => {
6
6
  return void 0;
7
7
  }
8
8
  };
9
+ const uppercaseFirstLetter = (value) => value.charAt(0).toUpperCase() + value.slice(1);
9
10
  export {
10
- tryParseJson
11
+ tryParseJson,
12
+ uppercaseFirstLetter
11
13
  };
12
14
  //# sourceMappingURL=sanitize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sources":["../../../src/utils/sanitize.ts"],"sourcesContent":["export const tryParseJson = <T>(json: string | null): T | undefined => {\n if (!json) return undefined\n try {\n return JSON.parse(json)\n } catch (_e) {\n return undefined\n }\n}\n"],"names":[],"mappings":"AAAa,MAAA,eAAe,CAAI,SAAuC;AACjE,MAAA,CAAC,KAAa,QAAA;AACd,MAAA;AACK,WAAA,KAAK,MAAM,IAAI;AAAA,WACf,IAAI;AACJ,WAAA;AAAA,EAAA;AAEX;"}
1
+ {"version":3,"file":"sanitize.js","sources":["../../../src/utils/sanitize.ts"],"sourcesContent":["export const tryParseJson = <T>(json: string | null): T | undefined => {\n if (!json) return undefined\n try {\n return JSON.parse(json)\n } catch (_e) {\n return undefined\n }\n}\n\nexport const uppercaseFirstLetter = (value: string) =>\n value.charAt(0).toUpperCase() + value.slice(1)\n"],"names":[],"mappings":"AAAO,MAAM,eAAe,CAAI,SAAuC;AACrE,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,IAAI;AACX,WAAO;AAAA,EACT;AACF;AAEO,MAAM,uBAAuB,CAAC,UACnC,MAAM,OAAO,CAAC,EAAE,YAAA,IAAgB,MAAM,MAAM,CAAC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sources":["../../../src/utils/storage.ts"],"sourcesContent":["export const getStorageItem = (key: string) => localStorage.getItem(key)\nexport const setStorageItem = (key: string, value: string) => {\n try {\n localStorage.setItem(key, value)\n } catch (_e) {\n return\n }\n}\n\nexport const TANSTACK_DEVTOOLS = 'tanstack_devtools'\nexport const TANSTACK_DEVTOOLS_STATE = 'tanstack_devtools_state'\nexport const TANSTACK_DEVTOOLS_SETTINGS = 'tanstack_devtools_settings'\n"],"names":[],"mappings":"AAAO,MAAM,iBAAiB,CAAC,QAAgB,aAAa,QAAQ,GAAG;AAC1D,MAAA,iBAAiB,CAAC,KAAa,UAAkB;AACxD,MAAA;AACW,iBAAA,QAAQ,KAAK,KAAK;AAAA,WACxB,IAAI;AACX;AAAA,EAAA;AAEJ;AAEO,MAAM,oBAAoB;AAC1B,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;"}
1
+ {"version":3,"file":"storage.js","sources":["../../../src/utils/storage.ts"],"sourcesContent":["export const getStorageItem = (key: string) => localStorage.getItem(key)\nexport const setStorageItem = (key: string, value: string) => {\n try {\n localStorage.setItem(key, value)\n } catch (_e) {\n return\n }\n}\n\nexport const TANSTACK_DEVTOOLS = 'tanstack_devtools'\nexport const TANSTACK_DEVTOOLS_STATE = 'tanstack_devtools_state'\nexport const TANSTACK_DEVTOOLS_SETTINGS = 'tanstack_devtools_settings'\n"],"names":[],"mappings":"AAAO,MAAM,iBAAiB,CAAC,QAAgB,aAAa,QAAQ,GAAG;AAChE,MAAM,iBAAiB,CAAC,KAAa,UAAkB;AAC5D,MAAI;AACF,iBAAa,QAAQ,KAAK,KAAK;AAAA,EACjC,SAAS,IAAI;AACX;AAAA,EACF;AACF;AAEO,MAAM,oBAAoB;AAC1B,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/devtools",
3
- "version": "0.0.0",
4
- "description": "Headless UI for creating advanced custom devtools, autocomplete, and dropdown components.",
3
+ "version": "0.1.1",
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",
7
7
  "repository": {
@@ -15,12 +15,7 @@
15
15
  "url": "https://github.com/sponsors/tannerlinsley"
16
16
  },
17
17
  "keywords": [
18
- "devtools",
19
- "autocomplete",
20
- "dropdown",
21
- "menu",
22
- "headless-ui",
23
- "nested"
18
+ "devtools"
24
19
  ],
25
20
  "type": "module",
26
21
  "types": "dist/esm/index.d.ts",
@@ -51,7 +46,10 @@
51
46
  "@solid-primitives/keyboard": "^1.2.8",
52
47
  "clsx": "^2.1.1",
53
48
  "goober": "^2.1.16",
54
- "solid-js": "^1.9.5"
49
+ "solid-js": "^1.9.7"
50
+ },
51
+ "peerDependencies": {
52
+ "solid-js": ">=1.9.7"
55
53
  },
56
54
  "devDependencies": {
57
55
  "vite-plugin-solid": "^2.11.6"
@@ -0,0 +1,43 @@
1
+ import { createSignal } from 'solid-js'
2
+ import { useStyles } from '../styles/use-styles'
3
+
4
+ interface CheckboxProps {
5
+ label?: string
6
+ checked?: boolean
7
+ onChange?: (checked: boolean) => void
8
+ description?: string
9
+ }
10
+
11
+ export function Checkbox(props: CheckboxProps) {
12
+ const styles = useStyles()
13
+ const [isChecked, setIsChecked] = createSignal(props.checked || false)
14
+
15
+ const handleChange = (e: Event) => {
16
+ const checked = (e.target as HTMLInputElement).checked
17
+ setIsChecked(checked)
18
+ props.onChange?.(checked)
19
+ }
20
+
21
+ return (
22
+ <div class={styles().checkboxContainer}>
23
+ <label class={styles().checkboxWrapper}>
24
+ <input
25
+ type="checkbox"
26
+ checked={isChecked()}
27
+ class={styles().checkbox}
28
+ onInput={handleChange}
29
+ />
30
+ <div class={styles().checkboxLabelContainer}>
31
+ {props.label && (
32
+ <span class={styles().checkboxLabel}>{props.label}</span>
33
+ )}
34
+ {props.description && (
35
+ <span class={styles().checkboxDescription}>
36
+ {props.description}
37
+ </span>
38
+ )}
39
+ </div>
40
+ </label>
41
+ </div>
42
+ )
43
+ }
@@ -1,3 +1,4 @@
1
+ import { useDevtoolsSettings } from '../context/use-devtools-context'
1
2
  import { useStyles } from '../styles/use-styles'
2
3
  import type { JSX } from 'solid-js/jsx-runtime'
3
4
 
@@ -7,11 +8,12 @@ export const ContentPanel = (props: {
7
8
  handleDragStart?: (e: any) => void
8
9
  }) => {
9
10
  const styles = useStyles()
11
+ const { settings } = useDevtoolsSettings()
10
12
  return (
11
13
  <div ref={props.ref} class={styles().devtoolsPanel}>
12
14
  {props.handleDragStart ? (
13
15
  <div
14
- class={styles().dragHandle}
16
+ class={styles().dragHandle(settings().panelLocation)}
15
17
  onMouseDown={props.handleDragStart}
16
18
  ></div>
17
19
  ) : null}
@@ -0,0 +1,42 @@
1
+ import { createSignal } from 'solid-js'
2
+ import { useStyles } from '../styles/use-styles'
3
+
4
+ interface InputProps {
5
+ label?: string
6
+ type?: 'text' | 'number' | 'password' | 'email'
7
+ value?: string
8
+ placeholder?: string
9
+ onChange?: (value: string) => void
10
+ description?: string
11
+ }
12
+
13
+ export function Input(props: InputProps) {
14
+ const styles = useStyles()
15
+ const [val, setVal] = createSignal(props.value || '')
16
+
17
+ const handleChange = (e: Event) => {
18
+ const value = (e.target as HTMLInputElement).value
19
+ setVal((prev) => (prev !== value ? value : prev))
20
+ props.onChange?.(value)
21
+ }
22
+
23
+ return (
24
+ <div class={styles().inputContainer}>
25
+ <div class={styles().inputWrapper}>
26
+ {props.label && (
27
+ <label class={styles().inputLabel}>{props.label}</label>
28
+ )}
29
+ {props.description && (
30
+ <p class={styles().inputDescription}>{props.description}</p>
31
+ )}
32
+ <input
33
+ type={props.type || 'text'}
34
+ class={styles().input}
35
+ value={val()}
36
+ placeholder={props.placeholder}
37
+ onInput={handleChange}
38
+ />
39
+ </div>
40
+ </div>
41
+ )
42
+ }
@@ -1,9 +1,8 @@
1
1
  import clsx from 'clsx'
2
- import { useHeight } from '../context/use-devtools-context'
2
+ import { useDevtoolsSettings, useHeight } from '../context/use-devtools-context'
3
3
  import { useStyles } from '../styles/use-styles'
4
4
  import { TANSTACK_DEVTOOLS } from '../utils/storage'
5
- import type { JSX } from 'solid-js/jsx-runtime'
6
- import type { Accessor } from 'solid-js'
5
+ import type { Accessor, JSX } from 'solid-js'
7
6
 
8
7
  export const MainPanel = (props: {
9
8
  isOpen: Accessor<boolean>
@@ -12,6 +11,7 @@ export const MainPanel = (props: {
12
11
  }) => {
13
12
  const styles = useStyles()
14
13
  const { height } = useHeight()
14
+ const { settings } = useDevtoolsSettings()
15
15
  return (
16
16
  <div
17
17
  id={TANSTACK_DEVTOOLS}
@@ -19,7 +19,7 @@ export const MainPanel = (props: {
19
19
  height: height() + 'px',
20
20
  }}
21
21
  class={clsx(
22
- styles().devtoolsPanelContainer,
22
+ styles().devtoolsPanelContainer(settings().panelLocation),
23
23
  styles().devtoolsPanelContainerAnimation(props.isOpen(), height()),
24
24
  styles().devtoolsPanelContainerVisibility(props.isOpen()),
25
25
  styles().devtoolsPanelContainerResizing(props.isResizing),
@@ -0,0 +1,50 @@
1
+ import { createSignal } from 'solid-js'
2
+ import { useStyles } from '../styles/use-styles'
3
+
4
+ interface SelectOption<T extends string | number> {
5
+ value: T
6
+ label: string
7
+ }
8
+
9
+ interface SelectProps<T extends string | number> {
10
+ label?: string
11
+ options: Array<SelectOption<T>>
12
+ value?: T
13
+ onChange?: (value: T) => void
14
+ description?: string
15
+ }
16
+
17
+ export function Select<T extends string | number>(props: SelectProps<T>) {
18
+ const styles = useStyles()
19
+ const [selected, setSelected] = createSignal(
20
+ props.value || props.options[0]?.value,
21
+ )
22
+
23
+ const handleChange = (e: Event) => {
24
+ const value = (e.target as HTMLSelectElement).value as T
25
+ setSelected((prev) => (prev !== value ? value : prev))
26
+ props.onChange?.(value)
27
+ }
28
+
29
+ return (
30
+ <div class={styles().selectContainer}>
31
+ <div class={styles().selectWrapper}>
32
+ {props.label && (
33
+ <label class={styles().selectLabel}>{props.label}</label>
34
+ )}
35
+ {props.description && (
36
+ <p class={styles().selectDescription}>{props.description}</p>
37
+ )}
38
+ <select
39
+ class={styles().select}
40
+ value={selected()}
41
+ onInput={handleChange}
42
+ >
43
+ {props.options.map((opt) => (
44
+ <option value={opt.value}>{opt.label}</option>
45
+ ))}
46
+ </select>
47
+ </div>
48
+ </div>
49
+ )
50
+ }
@@ -18,7 +18,7 @@ export const Trigger = ({
18
18
  return clsx(
19
19
  styles().mainCloseBtn,
20
20
  styles().mainCloseBtnPosition(settings().position),
21
- styles().mainCloseBtnAnimation(isOpen()),
21
+ styles().mainCloseBtnAnimation(isOpen(), settings().hideUntilHover),
22
22
  )
23
23
  })
24
24
  return (
@@ -0,0 +1,2 @@
1
+ export const PLUGIN_CONTAINER_ID = 'plugin-container'
2
+ export const PLUGIN_TITLE_CONTAINER_ID = 'plugin-title-container'
@@ -9,15 +9,56 @@ import {
9
9
  } from '../utils/storage'
10
10
  import { initialState } from './devtools-store'
11
11
  import type { DevtoolsStore } from './devtools-store'
12
- import type { Setter } from 'solid-js'
13
- import type { JSX } from 'solid-js/jsx-runtime'
12
+ import type { JSX, Setter } from 'solid-js'
14
13
 
15
- export interface DevtoolsPlugin {
14
+ export interface TanStackDevtoolsPlugin {
15
+ /**
16
+ * Name to be displayed in the devtools UI.
17
+ * If a string, it will be used as the plugin name.
18
+ * If a function, it will be called with the mount element.
19
+ *
20
+ * Example:
21
+ * ```ts
22
+ * {
23
+ * // If a string, it will be used as the plugin name
24
+ * name: "Your Plugin",
25
+ * render: () => {}
26
+ * }
27
+ * ```
28
+ * or
29
+ *
30
+ * ```ts
31
+ * {
32
+ * // If a function, it will be called with the mount element
33
+ * name: (el) => {
34
+ * el.innerText = "Your Plugin Name"
35
+ * // Your name logic here
36
+ * },
37
+ * render: () => {}
38
+ * }
39
+ * ```
40
+ */
16
41
  name: string | ((el: HTMLHeadingElement) => void)
17
- id: string
42
+ /**
43
+ * Unique identifier for the plugin.
44
+ * If not provided, it will be generated based on the name.
45
+ */
46
+ id?: string
47
+ /**
48
+ * Render the plugin UI by using the provided element. This function will be called
49
+ * when the plugin tab is clicked and expected to be mounted.
50
+ * @param el The mount element for the plugin.
51
+ * @returns void
52
+ *
53
+ * Example:
54
+ * ```ts
55
+ * render: (el) => {
56
+ * el.innerHTML = "<h1>Your Plugin</h1>"
57
+ * }
58
+ * ```
59
+ */
18
60
  render: (el: HTMLDivElement) => void
19
61
  }
20
-
21
62
  export const DevtoolsContext = createContext<{
22
63
  store: DevtoolsStore
23
64
  setStore: Setter<DevtoolsStore>
@@ -25,8 +66,8 @@ export const DevtoolsContext = createContext<{
25
66
 
26
67
  interface ContextProps {
27
68
  children: JSX.Element
28
- plugins?: Array<DevtoolsPlugin>
29
- config?: DevtoolsSettings
69
+ plugins?: Array<TanStackDevtoolsPlugin>
70
+ config?: TanStackDevtoolsConfig
30
71
  }
31
72
 
32
73
  const getSettings = () => {
@@ -37,16 +78,36 @@ const getSettings = () => {
37
78
  }
38
79
  }
39
80
 
81
+ const generatePluginId = (plugin: TanStackDevtoolsPlugin, index: number) => {
82
+ // if set by user, return the plugin id
83
+ if (plugin.id) {
84
+ return plugin.id
85
+ }
86
+ if (typeof plugin.name === 'string') {
87
+ // if name is a string, use it to generate an id
88
+ return plugin.name.toLowerCase().replace(' ', '-')
89
+ }
90
+ // Name is JSX? return the index as a string
91
+ return index.toString()
92
+ }
93
+
40
94
  const getExistingStateFromStorage = (
41
- config?: DevtoolsSettings,
42
- plugins?: Array<DevtoolsPlugin>,
95
+ config?: TanStackDevtoolsConfig,
96
+ plugins?: Array<TanStackDevtoolsPlugin>,
43
97
  ) => {
44
98
  const existingState = getStorageItem(TANSTACK_DEVTOOLS_STATE)
45
99
  const settings = getSettings()
46
100
 
47
101
  const state: DevtoolsStore = {
48
102
  ...initialState,
49
- plugins: plugins || [],
103
+ plugins:
104
+ plugins?.map((plugin, i) => {
105
+ const id = generatePluginId(plugin, i)
106
+ return {
107
+ ...plugin,
108
+ id,
109
+ }
110
+ }) || [],
50
111
  state: {
51
112
  ...initialState.state,
52
113
  ...(existingState ? JSON.parse(existingState) : {}),
@@ -60,7 +121,7 @@ const getExistingStateFromStorage = (
60
121
  return state
61
122
  }
62
123
 
63
- export type DevtoolsSettings = DevtoolsStore['settings']
124
+ export type TanStackDevtoolsConfig = DevtoolsStore['settings']
64
125
 
65
126
  export const DevtoolsProvider = (props: ContextProps) => {
66
127
  const [store, setStore] = createStore(
@@ -1,5 +1,5 @@
1
1
  import type { TabName } from '../tabs'
2
- import type { DevtoolsPlugin } from './devtools-context'
2
+ import type { TanStackDevtoolsPlugin } from './devtools-context'
3
3
 
4
4
  type ModifierKey = 'Alt' | 'Control' | 'Meta' | 'Shift'
5
5
  type KeyboardKey = ModifierKey | (string & {})
@@ -54,10 +54,10 @@ export type DevtoolsStore = {
54
54
  state: {
55
55
  activeTab: TabName
56
56
  height: number
57
- activePlugin?: DevtoolsPlugin | undefined
57
+ activePlugin?: string | undefined
58
58
  persistOpen: boolean
59
59
  }
60
- plugins?: Array<DevtoolsPlugin>
60
+ plugins?: Array<TanStackDevtoolsPlugin>
61
61
  }
62
62
 
63
63
  export const initialState: DevtoolsStore = {
@@ -1,6 +1,5 @@
1
1
  import { createMemo, useContext } from 'solid-js'
2
2
  import { DevtoolsContext } from './devtools-context.jsx'
3
- import type { DevtoolsPlugin } from './devtools-context.jsx'
4
3
  /* import type { DevtoolsPlugin } from './devtools-context' */
5
4
  import type { DevtoolsStore } from './devtools-store.js'
6
5
 
@@ -24,12 +23,12 @@ export const usePlugins = () => {
24
23
  const plugins = createMemo(() => store.plugins)
25
24
  const activePlugin = createMemo(() => store.state.activePlugin)
26
25
 
27
- const setActivePlugin = (plugin: DevtoolsPlugin) => {
26
+ const setActivePlugin = (pluginId: string) => {
28
27
  setStore((prev) => ({
29
28
  ...prev,
30
29
  state: {
31
30
  ...prev.state,
32
- activePlugin: plugin,
31
+ activePlugin: pluginId,
33
32
  },
34
33
  }))
35
34
  }
package/src/core.tsx CHANGED
@@ -3,29 +3,53 @@ import { Portal, render } from 'solid-js/web'
3
3
  import { DevtoolsProvider } from './context/devtools-context'
4
4
  import { initialState } from './context/devtools-store'
5
5
  import type {
6
- DevtoolsPlugin,
7
- DevtoolsSettings,
6
+ TanStackDevtoolsConfig,
7
+ TanStackDevtoolsPlugin,
8
8
  } from './context/devtools-context'
9
9
 
10
- export interface DevtoolsOptions {
11
- options?: Partial<DevtoolsSettings>
12
- plugins?: Array<DevtoolsPlugin>
10
+ export interface TanStackDevtoolsInit {
11
+ /**
12
+ * Configuration for the devtools shell. These configuration options are used to set the
13
+ * initial state of the devtools when it is started for the first time. Afterwards,
14
+ * the settings are persisted in local storage and changed through the settings panel.
15
+ */
16
+ config?: Partial<TanStackDevtoolsConfig>
17
+ /**
18
+ * Array of plugins to be used in the devtools.
19
+ * Each plugin has a `render` function that gives you the dom node to mount into
20
+ *
21
+ * Example:
22
+ * ```ts
23
+ * const devtools = new TanStackDevtoolsCore({
24
+ * plugins: [
25
+ * {
26
+ * id: "your-plugin-id",
27
+ * name: "Your Plugin",
28
+ * render: (el) => {
29
+ * // Your render logic here
30
+ * },
31
+ * },
32
+ * ],
33
+ * })
34
+ * ```
35
+ */
36
+ plugins?: Array<TanStackDevtoolsPlugin>
13
37
  }
14
38
 
15
- class TanStackDevtoolsCore {
16
- #options: DevtoolsSettings = {
39
+ export class TanStackDevtoolsCore {
40
+ #config: TanStackDevtoolsConfig = {
17
41
  ...initialState.settings,
18
42
  }
19
- #plugins: Array<DevtoolsPlugin> = []
43
+ #plugins: Array<TanStackDevtoolsPlugin> = []
20
44
  #isMounted = false
21
45
  #dispose?: () => void
22
46
  #Component: any
23
47
 
24
- constructor(config: DevtoolsOptions) {
25
- this.#plugins = config.plugins || []
26
- this.#options = {
27
- ...this.#options,
28
- ...config.options,
48
+ constructor(init: TanStackDevtoolsInit) {
49
+ this.#plugins = init.plugins || []
50
+ this.#config = {
51
+ ...this.#config,
52
+ ...init.config,
29
53
  }
30
54
  }
31
55
 
@@ -40,7 +64,7 @@ class TanStackDevtoolsCore {
40
64
  const Devtools = this.#Component
41
65
 
42
66
  return (
43
- <DevtoolsProvider plugins={this.#plugins} config={this.#options}>
67
+ <DevtoolsProvider plugins={this.#plugins} config={this.#config}>
44
68
  <Portal mount={mountTo}>
45
69
  <Devtools />
46
70
  </Portal>
@@ -60,12 +84,10 @@ class TanStackDevtoolsCore {
60
84
  this.#isMounted = false
61
85
  }
62
86
 
63
- setOptions(options: Partial<DevtoolsOptions>) {
64
- this.#options = {
65
- ...this.#options,
66
- ...options,
87
+ setConfig(config: Partial<TanStackDevtoolsInit>) {
88
+ this.#config = {
89
+ ...this.#config,
90
+ ...config,
67
91
  }
68
92
  }
69
93
  }
70
-
71
- export { TanStackDevtoolsCore as TanStackRouterDevtoolsCore }
package/src/devtools.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { createEffect, createSignal } from 'solid-js'
1
+ import { Show, createEffect, createSignal } from 'solid-js'
2
2
  import { createShortcut } from '@solid-primitives/keyboard'
3
3
  import {
4
4
  useDevtoolsSettings,
@@ -28,24 +28,27 @@ export default function DevTools() {
28
28
  setIsOpen(!open)
29
29
  setPersistOpen(!open)
30
30
  }
31
-
31
+ createEffect(() => {})
32
32
  // Used to resize the panel
33
33
  const handleDragStart = (
34
34
  panelElement: HTMLDivElement | undefined,
35
35
  startEvent: MouseEvent,
36
36
  ) => {
37
37
  if (startEvent.button !== 0) return // Only allow left click for drag
38
-
38
+ if (!panelElement) return
39
39
  setIsResizing(true)
40
40
 
41
41
  const dragInfo = {
42
- originalHeight: panelElement?.getBoundingClientRect().height ?? 0,
42
+ originalHeight: panelElement.getBoundingClientRect().height,
43
43
  pageY: startEvent.pageY,
44
44
  }
45
45
 
46
46
  const run = (moveEvent: MouseEvent) => {
47
47
  const delta = dragInfo.pageY - moveEvent.pageY
48
- const newHeight = dragInfo.originalHeight + delta
48
+ const newHeight =
49
+ settings().panelLocation === 'bottom'
50
+ ? dragInfo.originalHeight + delta
51
+ : dragInfo.originalHeight - delta
49
52
 
50
53
  setHeight(newHeight)
51
54
 
@@ -72,7 +75,8 @@ export default function DevTools() {
72
75
  const previousValue = rootEl()?.parentElement?.style.paddingBottom
73
76
 
74
77
  const run = () => {
75
- const containerHeight = panelRef!.getBoundingClientRect().height
78
+ if (!panelRef) return
79
+ const containerHeight = panelRef.getBoundingClientRect().height
76
80
  if (rootEl()?.parentElement) {
77
81
  setRootEl((prev) => {
78
82
  if (prev?.parentElement) {
@@ -126,21 +130,33 @@ export default function DevTools() {
126
130
  el?.style.setProperty('--tsrd-font-size', fontSize)
127
131
  }
128
132
  })
129
- createShortcut(settings().openHotkey, () => {
130
- toggleOpen()
133
+ createEffect(() => {
134
+ createShortcut(settings().openHotkey, () => {
135
+ toggleOpen()
136
+ })
131
137
  })
138
+
139
+ createEffect(() => {})
132
140
  return (
133
141
  <div ref={setRootEl} data-testid={TANSTACK_DEVTOOLS}>
134
- <Trigger isOpen={isOpen} setIsOpen={toggleOpen} />
135
- <MainPanel isResizing={isResizing} isOpen={isOpen}>
136
- <ContentPanel
137
- ref={(ref) => (panelRef = ref)}
138
- handleDragStart={(e) => handleDragStart(panelRef, e)}
139
- >
140
- <Tabs toggleOpen={toggleOpen} />
141
- <TabContent />
142
- </ContentPanel>
143
- </MainPanel>
142
+ <Show
143
+ when={
144
+ settings().requireUrlFlag
145
+ ? window.location.search.includes(settings().urlFlag)
146
+ : true
147
+ }
148
+ >
149
+ <Trigger isOpen={isOpen} setIsOpen={toggleOpen} />
150
+ <MainPanel isResizing={isResizing} isOpen={isOpen}>
151
+ <ContentPanel
152
+ ref={(ref) => (panelRef = ref)}
153
+ handleDragStart={(e) => handleDragStart(panelRef, e)}
154
+ >
155
+ <Tabs toggleOpen={toggleOpen} />
156
+ <TabContent />
157
+ </ContentPanel>
158
+ </MainPanel>
159
+ </Show>
144
160
  </div>
145
161
  )
146
162
  }