Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/react/start-bun/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-devtools": "^0.7.0",
"@tanstack/react-devtools": "^0.9.0",
"@tanstack/react-router": "^1.166.2",
"@tanstack/react-router-devtools": "^1.166.2",
"@tanstack/react-router-ssr-query": "^1.166.2",
Expand Down
2 changes: 1 addition & 1 deletion examples/react/start-i18n-paraglide/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"@tanstack/react-devtools": "^0.7.0",
"@tanstack/react-devtools": "^0.9.0",
"@tanstack/react-router": "^1.166.2",
"@tanstack/react-router-devtools": "^1.166.2",
"@tanstack/react-start": "^1.166.2",
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,8 @@
"pnpm": {
"overrides": {
"@types/babel__traverse": "^7.28.0",
"vite-plugin-dts": "4.0.3",
"solid-js": "1.9.10",
"react": "$react",
"vite-plugin-dts": "4.0.3",
"react": "$react",
"react-dom": "$react-dom",
"@types/react": "$@types/react",
"@types/react-dom": "$@types/react-dom",
Expand Down
5 changes: 3 additions & 2 deletions packages/router-devtools-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@
"tiny-invariant": "^1.3.3"
},
"devDependencies": {
"solid-js": "^1.9.10",
"@solidjs/web": "2.0.0-beta.1",
"solid-js": "2.0.0-beta.1",
"vite": "*",
"vite-plugin-solid": "^2.11.10"
"vite-plugin-solid": "3.0.0-next.2"
},
"peerDependencies": {
"@tanstack/router-core": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
createMemo,
createSignal,
onCleanup,
untrack,
} from 'solid-js'
import { useDevtoolsOnClose } from './context'
import { useStyles } from './useStyles'
Expand Down Expand Up @@ -280,32 +279,32 @@ export const BaseTanStackRouterDevtoolsPanel =
const [history, setHistory] = createSignal<Array<AnyRouteMatch>>([])
const [hasHistoryOverflowed, setHasHistoryOverflowed] = createSignal(false)

createEffect(() => {
const matches = routerState().matches
const currentMatch = matches[matches.length - 1]
if (!currentMatch) {
return
}
// Read history WITHOUT tracking it to avoid infinite loops
const historyUntracked = untrack(() => history())
const lastMatch = historyUntracked[0]
const sameLocation =
lastMatch &&
lastMatch.pathname === currentMatch.pathname &&
JSON.stringify(lastMatch.search ?? {}) ===
JSON.stringify(currentMatch.search ?? {})
if (!lastMatch || !sameLocation) {
if (historyUntracked.length >= HISTORY_LIMIT) {
setHasHistoryOverflowed(true)
createEffect(
() => routerState().matches,
(matches) => {
const currentMatch = matches[matches.length - 1]
if (!currentMatch) {
return
}
setHistory((prev) => {
const newHistory = [currentMatch, ...prev]
// truncate to ensure we don't overflow too much the ui
newHistory.splice(HISTORY_LIMIT)
return newHistory
})
}
})
const lastMatch = history()[0]
const sameLocation =
lastMatch &&
lastMatch.pathname === currentMatch.pathname &&
JSON.stringify(lastMatch.search ?? {}) ===
JSON.stringify(currentMatch.search ?? {})
if (!lastMatch || !sameLocation) {
if (history().length >= HISTORY_LIMIT) {
setHasHistoryOverflowed(true)
}
setHistory((prev) => {
const newHistory = [currentMatch, ...prev]
// truncate to ensure we don't overflow too much the ui
newHistory.splice(HISTORY_LIMIT)
return newHistory
})
}
},
)

const activeMatch = createMemo(() => {
const matches = [
Expand Down Expand Up @@ -378,7 +377,7 @@ export const BaseTanStackRouterDevtoolsPanel =
{...otherPanelProps}
>
{handleDragStart ? (
<div class={styles().dragHandle} onMouseDown={handleDragStart}></div>
<div class={styles().dragHandle} on:mousedown={handleDragStart}></div>
) : null}
<button
class={styles().panelCloseBtn}
Expand Down Expand Up @@ -566,7 +565,7 @@ export const BaseTanStackRouterDevtoolsPanel =
{(match, index) => (
<li
class={cx(
styles().matchRow(match === activeMatch()),
styles().matchRow(match() === activeMatch()),
)}
>
<div
Expand All @@ -579,18 +578,18 @@ export const BaseTanStackRouterDevtoolsPanel =
<NavigateLink
left={
<NavigateButton
to={match.pathname}
params={match.params}
search={match.search}
to={match().pathname}
params={match().params}
search={match().search}
router={router}
/>
}
right={
<AgeTicker match={match} router={router} />
<AgeTicker match={match()} router={router} />
}
>
<code class={styles().matchID}>
{`${match.routeId === rootRouteId ? rootRouteId : match.pathname}`}
{`${match().routeId === rootRouteId ? rootRouteId : match().pathname}`}
</code>
</NavigateLink>
</li>
Expand Down
2 changes: 1 addition & 1 deletion packages/router-devtools-core/src/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export function Explorer({
)
}

const stylesFactory = (shadowDOMTarget?: ShadowRoot) => {
const stylesFactory = (shadowDOMTarget?: ShadowRoot | null) => {
const { colors, font, size, alpha, shadow, border } = tokens
const { fontFamily, lineHeight, size: fontSize } = font
const css = shadowDOMTarget
Expand Down
114 changes: 58 additions & 56 deletions packages/router-devtools-core/src/FloatingTanStackRouterDevtools.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { clsx as cx } from 'clsx'

import { createEffect, createMemo, createSignal } from 'solid-js'
import { Dynamic } from 'solid-js/web'
import { Dynamic } from '@solidjs/web'

import { DevtoolsOnCloseContext } from './context'
import { useIsMounted } from './utils'
Expand Down Expand Up @@ -69,9 +69,7 @@ export function FloatingTanStackRouterDevtools({
shadowDOMTarget,
}: FloatingDevtoolsOptions): JSX.Element | null {
const [rootEl, setRootEl] = createSignal<HTMLDivElement>()

// eslint-disable-next-line prefer-const
let panelRef: HTMLDivElement | undefined = undefined
const [panelRef, setPanelRef] = createSignal<HTMLDivElement>()

const [isOpen, setIsOpen] = useLocalStorage(
'tanstackRouterDevtoolsOpen',
Expand Down Expand Up @@ -105,6 +103,11 @@ export function FloatingTanStackRouterDevtools({
const delta = dragInfo.pageY - moveEvent.pageY
const newHeight = dragInfo.originalHeight + delta

// Directly manipulate DOM for immediate visual feedback during drag
if (panelElement) {
panelElement.style.height = `${newHeight}px`
}

setDevtoolsHeight(newHeight)

if (newHeight < 70) {
Expand All @@ -117,7 +120,7 @@ export function FloatingTanStackRouterDevtools({
const unsub = () => {
setIsResizing(false)
document.removeEventListener('mousemove', run)
document.removeEventListener('mouseUp', unsub)
document.removeEventListener('mouseup', unsub)
}

document.addEventListener('mousemove', run)
Expand All @@ -126,62 +129,61 @@ export function FloatingTanStackRouterDevtools({

const isButtonClosed = isOpen() ?? false

createEffect(() => {
setIsResolvedOpen(isOpen() ?? false)
})

createEffect(() => {
if (isResolvedOpen()) {
const previousValue = rootEl()?.parentElement?.style.paddingBottom
createEffect(
() => isOpen(),
(val) => {
setIsResolvedOpen(val ?? false)
},
)

const run = () => {
const containerHeight = panelRef!.getBoundingClientRect().height
if (rootEl()?.parentElement) {
setRootEl((prev) => {
if (prev?.parentElement) {
prev.parentElement.style.paddingBottom = `${containerHeight}px`
}
return prev
})
createEffect(
() => ({
open: isResolvedOpen(),
root: rootEl(),
panel: panelRef(),
}),
({ open, root, panel }) => {
if (open) {
const previousValue = root?.parentElement?.style.paddingBottom

const run = () => {
const containerHeight = panel?.getBoundingClientRect().height ?? 0
if (root?.parentElement) {
root.parentElement.style.paddingBottom = `${containerHeight}px`
}
}
}

run()
run()

if (typeof window !== 'undefined') {
window.addEventListener('resize', run)
if (typeof window !== 'undefined') {
window.addEventListener('resize', run)

return () => {
window.removeEventListener('resize', run)
if (rootEl()?.parentElement && typeof previousValue === 'string') {
setRootEl((prev) => {
prev!.parentElement!.style.paddingBottom = previousValue
return prev
})
return () => {
window.removeEventListener('resize', run)
if (root?.parentElement && typeof previousValue === 'string') {
root.parentElement.style.paddingBottom = previousValue
}
}
}
} else {
// Reset padding when devtools are closed
if (root?.parentElement) {
root.parentElement.removeAttribute('style')
}
}
} else {
// Reset padding when devtools are closed
if (rootEl()?.parentElement) {
setRootEl((prev) => {
if (prev?.parentElement) {
prev.parentElement.removeAttribute('style')
}
return prev
})
}
}
return
})
return
},
)

createEffect(() => {
if (rootEl()) {
const el = rootEl()
const fontSize = getComputedStyle(el!).fontSize
el?.style.setProperty('--tsrd-font-size', fontSize)
}
})
createEffect(
() => rootEl(),
(el) => {
if (el) {
const fontSize = getComputedStyle(el).fontSize
el.style.setProperty('--tsrd-font-size', fontSize)
}
},
)

const { style: panelStyle = {}, ...otherPanelProps } = panelProps as {
style?: Record<string, any>
Expand Down Expand Up @@ -239,28 +241,28 @@ export function FloatingTanStackRouterDevtools({
ref={setRootEl}
class="TanStackRouterDevtools"
>
<DevtoolsOnCloseContext.Provider
<DevtoolsOnCloseContext
value={{
onCloseClick: onCloseClick ?? (() => {}),
}}
>
{/* {router() ? ( */}
<BaseTanStackRouterDevtoolsPanel
ref={panelRef}
ref={setPanelRef}
{...otherPanelProps}
router={router}
routerState={routerState}
className={basePanelClass}
style={basePanelStyle}
isOpen={isResolvedOpen()}
setIsOpen={setIsOpen}
handleDragStart={(e) => handleDragStart(panelRef, e)}
handleDragStart={(e) => handleDragStart(panelRef(), e)}
shadowDOMTarget={shadowDOMTarget}
/>
{/* ) : (
<p>No router</p>
)} */}
</DevtoolsOnCloseContext.Provider>
</DevtoolsOnCloseContext>

<button
type="button"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createSignal, lazy } from 'solid-js'
import { render } from 'solid-js/web'
import { render } from '@solidjs/web'
import { ShadowDomTargetContext } from './context'
import type { AnyRouter } from '@tanstack/router-core'
import type { Signal } from 'solid-js'
Expand Down Expand Up @@ -105,7 +105,7 @@ export class TanStackRouterDevtoolsCore {
}

return (
<ShadowDomTargetContext.Provider value={shadowDOMTarget}>
<ShadowDomTargetContext value={shadowDOMTarget ?? null}>
<Devtools
position={position}
initialIsOpen={initialIsOpen}
Expand All @@ -117,7 +117,7 @@ export class TanStackRouterDevtoolsCore {
toggleButtonProps={toggleButtonProps}
containerElement={containerElement}
/>
</ShadowDomTargetContext.Provider>
</ShadowDomTargetContext>
)
}, el)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render } from 'solid-js/web'
import { render } from '@solidjs/web'
import { createSignal, lazy } from 'solid-js'
import { DevtoolsOnCloseContext, ShadowDomTargetContext } from './context'
import type { JSX } from 'solid-js'
Expand Down Expand Up @@ -91,8 +91,8 @@ export class TanStackRouterDevtoolsPanelCore {
}

return (
<ShadowDomTargetContext.Provider value={shadowDOMTarget}>
<DevtoolsOnCloseContext.Provider
<ShadowDomTargetContext value={shadowDOMTarget ?? null}>
<DevtoolsOnCloseContext
value={{
onCloseClick: () => {},
}}
Expand All @@ -105,8 +105,8 @@ export class TanStackRouterDevtoolsPanelCore {
style={style}
className={className}
/>
</DevtoolsOnCloseContext.Provider>
</ShadowDomTargetContext.Provider>
</DevtoolsOnCloseContext>
</ShadowDomTargetContext>
)
}, el)

Expand Down
Loading
Loading