From 44cd0990834f5f0f212b3660840a658e9cfbd1e1 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Fri, 24 Oct 2025 12:53:23 +0200 Subject: [PATCH 01/32] tanstack migration init --- package.json | 8 +- packages/react-router-devtools/package.json | 14 +- .../src/client/components/Breakpoints.tsx | 23 - .../src/client/components/LiveUrls.tsx | 33 - .../src/client/components/Trigger.tsx | 60 -- .../src/client/context/RDTContext.tsx | 25 +- .../src/client/context/rdtReducer.ts | 243 +------- .../src/client/context/terminal/types.ts | 12 - .../src/client/context/useRDTContext.ts | 22 - .../src/client/embedded-dev-tools.tsx | 14 +- .../hooks/detached/useCheckIfStillDetached.ts | 61 -- .../hooks/detached/useListenToRouteChange.ts | 53 -- .../client/hooks/detached/useRemoveBody.ts | 20 - .../hooks/detached/useResetDetachmentCheck.ts | 10 - .../detached/useSyncStateWhenDetached.ts | 42 -- .../src/client/hooks/useResize.ts | 56 -- .../src/client/hooks/useSetRouteBoundaries.ts | 14 +- .../src/client/hooks/useTimelineHandler.ts | 9 +- .../src/client/init/root.tsx | 36 +- .../{components/Logo.tsx => init/trigger.svg} | 50 +- .../src/client/layout/ContentPanel.tsx | 1 - .../src/client/layout/MainPanel.tsx | 44 +- .../src/client/layout/Tabs.tsx | 64 +- .../src/client/react-router-dev-tools.tsx | 122 +--- .../src/client/tabs/PageTab.tsx | 2 +- .../src/client/tabs/RoutesTab.tsx | 7 +- .../src/client/tabs/SettingsTab.tsx | 143 ----- .../react-router-devtools/src/gradients.css | 14 +- packages/react-router-devtools/src/input.css | 2 +- .../react-router-devtools/src/vite/plugin.tsx | 64 +- .../react-router-devtools/tailwind.config.js | 4 +- .../tsup-client.config.ts | 3 + packages/react-router-devtools/tsup.config.ts | 3 + pnpm-lock.yaml | 577 ++++++++++++------ test-apps/react-router-vite/app/root.tsx | 8 +- test-apps/react-router-vite/package.json | 2 +- test-apps/react-router-vite/vite.config.ts | 20 +- 37 files changed, 480 insertions(+), 1405 deletions(-) delete mode 100644 packages/react-router-devtools/src/client/components/Breakpoints.tsx delete mode 100644 packages/react-router-devtools/src/client/components/LiveUrls.tsx delete mode 100644 packages/react-router-devtools/src/client/components/Trigger.tsx delete mode 100644 packages/react-router-devtools/src/client/context/terminal/types.ts delete mode 100644 packages/react-router-devtools/src/client/hooks/detached/useCheckIfStillDetached.ts delete mode 100644 packages/react-router-devtools/src/client/hooks/detached/useListenToRouteChange.ts delete mode 100644 packages/react-router-devtools/src/client/hooks/detached/useRemoveBody.ts delete mode 100644 packages/react-router-devtools/src/client/hooks/detached/useResetDetachmentCheck.ts delete mode 100644 packages/react-router-devtools/src/client/hooks/detached/useSyncStateWhenDetached.ts delete mode 100644 packages/react-router-devtools/src/client/hooks/useResize.ts rename packages/react-router-devtools/src/client/{components/Logo.tsx => init/trigger.svg} (79%) diff --git a/package.json b/package.json index 44eb81b2..598e87b3 100644 --- a/package.json +++ b/package.json @@ -64,11 +64,11 @@ "nx": { "includedScripts": ["test:unused", "check", "test:deps"] }, - "overrides": { - "react-router-devtools": "workspace:*" - }, "pnpm": { - "onlyBuiltDependencies": ["esbuild", "msw"] + "onlyBuiltDependencies": ["esbuild", "msw"], + "overrides": { + "react-router-devtools": "workspace:*" + } }, "private": true } diff --git a/packages/react-router-devtools/package.json b/packages/react-router-devtools/package.json index 490d7f49..17354257 100644 --- a/packages/react-router-devtools/package.json +++ b/packages/react-router-devtools/package.json @@ -2,7 +2,7 @@ "name": "react-router-devtools", "description": "Devtools for React Router - debug, trace, find hydration errors, catch bugs and inspect server/client data with react-router-devtools", "author": "Alem Tuzlak", - "version": "5.1.6", + "version": "5.1.3", "license": "MIT", "keywords": [ "react-router", @@ -59,9 +59,7 @@ "require": "./dist/client.css" } }, - "files": [ - "dist" - ], + "files": ["dist"], "repository": { "type": "git", "url": "git+https://github.com/forge-42/react-router-devtools.git" @@ -108,9 +106,9 @@ "vite": ">=5.0.0 || >=6.0.0" }, "devDependencies": { - "@react-router/dev": "^7.5.3", - "@react-router/node": "^7.5.3", - "@react-router/serve": "7.1.4", + "@react-router/dev": "7.5.3", + "@react-router/node": "7.5.3", + "@react-router/serve": "7.5.3", "@testing-library/dom": "^10.4.0", "@testing-library/react": "16.2.0", "@types/babel__core": "^7.20.5", @@ -142,6 +140,8 @@ "@babel/types": "^7.26.10", "@radix-ui/react-accordion": "^1.2.2", "@radix-ui/react-select": "^2.1.5", + "@tanstack/devtools-vite": "^0.3.8", + "@tanstack/react-devtools": "^0.7.7", "beautify": "^0.0.8", "bippy": "^0.3.7", "chalk": "5.4.1", diff --git a/packages/react-router-devtools/src/client/components/Breakpoints.tsx b/packages/react-router-devtools/src/client/components/Breakpoints.tsx deleted file mode 100644 index 3a3d39e0..00000000 --- a/packages/react-router-devtools/src/client/components/Breakpoints.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import clsx from "clsx" -import { useSettingsContext } from "../context/useRDTContext" -import { useOnWindowResize } from "../hooks/useOnWindowResize" - -export const Breakpoints = () => { - const { width } = useOnWindowResize() - const { settings } = useSettingsContext() - const breakpoints = settings.breakpoints - const show = settings.showBreakpointIndicator - const breakpoint = breakpoints.find((bp) => bp.min <= width && bp.max >= width) - if (!breakpoint || !breakpoint.name || !show) { - return null - } - return ( -
- {breakpoint?.name} -
- ) -} diff --git a/packages/react-router-devtools/src/client/components/LiveUrls.tsx b/packages/react-router-devtools/src/client/components/LiveUrls.tsx deleted file mode 100644 index db72793d..00000000 --- a/packages/react-router-devtools/src/client/components/LiveUrls.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import clsx from "clsx" -import { Link, useLocation } from "react-router" -import { useSettingsContext } from "../context/useRDTContext" - -export const LiveUrls = () => { - const { settings } = useSettingsContext() - const location = useLocation() - const envsPosition = settings.liveUrlsPosition - const envsClassName = { - "bottom-0": envsPosition === "bottom-left" || envsPosition === "bottom-right", - "top-0": envsPosition === "top-left" || envsPosition === "top-right", - "right-0": envsPosition === "bottom-right" || envsPosition === "top-right", - "left-0": envsPosition === "bottom-left" || envsPosition === "top-left", - } - if (settings.liveUrls.length === 0) return null - return ( -
- {settings.liveUrls.map((env) => { - return ( - - {env.name} - - ) - })} -
- ) -} diff --git a/packages/react-router-devtools/src/client/components/Trigger.tsx b/packages/react-router-devtools/src/client/components/Trigger.tsx deleted file mode 100644 index 1889b40c..00000000 --- a/packages/react-router-devtools/src/client/components/Trigger.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import clsx from "clsx" -import { usePersistOpen, useSettingsContext } from "../context/useRDTContext.js" -import { Logo } from "./Logo.js" - -export const Trigger = ({ - isOpen, - setIsOpen, -}: { - isOpen: boolean - setIsOpen: React.Dispatch> -}) => { - const { settings } = useSettingsContext() - const { setPersistOpen } = usePersistOpen() - const { hideUntilHover, position } = settings - const handleHover = (e: React.MouseEvent, event: "enter" | "leave") => { - if (!hideUntilHover) return - const classesToRemove = "opacity-0" - const classesToAdd = "opacity-100" - if (event === "enter") { - e.currentTarget.classList.remove(classesToRemove) - e.currentTarget.classList.add(classesToAdd) - } - if (event === "leave") { - e.currentTarget.classList.remove(classesToAdd) - e.currentTarget.classList.add(classesToRemove) - } - } - - return ( - - ) -} diff --git a/packages/react-router-devtools/src/client/context/RDTContext.tsx b/packages/react-router-devtools/src/client/context/RDTContext.tsx index 4329c392..648ca51a 100644 --- a/packages/react-router-devtools/src/client/context/RDTContext.tsx +++ b/packages/react-router-devtools/src/client/context/RDTContext.tsx @@ -2,7 +2,6 @@ import type { Dispatch } from "react" import type React from "react" import { createContext, useEffect, useMemo, useReducer } from "react" import { bigIntReplacer } from "../../shared/bigint-util.js" -import { useRemoveBody } from "../hooks/detached/useRemoveBody.js" import { checkIsDetached, checkIsDetachedOwner, checkIsDetachedWindow } from "../utils/detached.js" import { tryParseJson } from "../utils/sanitize.js" import { @@ -85,8 +84,6 @@ export const getExistingStateFromStorage = (config?: RdtClientConfig & { editorN ...config, ...settings, editorName: config?.editorName ?? initialState.settings.editorName, - liveUrls: config?.liveUrls ?? initialState.settings.liveUrls, - breakpoints: config?.breakpoints ?? initialState.settings.breakpoints, }, detachedWindow, detachedWindowOwner, @@ -96,23 +93,7 @@ export const getExistingStateFromStorage = (config?: RdtClientConfig & { editorN export type RdtClientConfig = Pick< ReactRouterDevtoolsState["settings"], - | "defaultOpen" - | "breakpoints" - | "showBreakpointIndicator" - | "showRouteBoundariesOn" - | "expansionLevel" - | "liveUrls" - | "position" - | "height" - | "minHeight" - | "maxHeight" - | "hideUntilHover" - | "panelLocation" - | "requireUrlFlag" - | "openHotkey" - | "urlFlag" - | "enableInspector" - | "routeBoundaryGradient" + "showRouteBoundariesOn" | "expansionLevel" | "routeBoundaryGradient" > export const RDTContextProvider = ({ children, config }: ContextProps) => { @@ -120,10 +101,8 @@ export const RDTContextProvider = ({ children, config }: ContextProps) => { // biome-ignore lint/correctness/useExhaustiveDependencies: investigate const value = useMemo(() => ({ state, dispatch }), [state, dispatch]) - useRemoveBody(state) - useEffect(() => { - const { settings, detachedWindow, detachedWindowOwner, ...rest } = state + const { settings, ...rest } = state // Store user settings for dev tools into local storage setStorageItem(REACT_ROUTER_DEV_TOOLS_SETTINGS, JSON.stringify(settings)) // Store general state into local storage diff --git a/packages/react-router-devtools/src/client/context/rdtReducer.ts b/packages/react-router-devtools/src/client/context/rdtReducer.ts index 98dcc1eb..26a60e99 100644 --- a/packages/react-router-devtools/src/client/context/rdtReducer.ts +++ b/packages/react-router-devtools/src/client/context/rdtReducer.ts @@ -1,7 +1,6 @@ import type { ActionEvent, LoaderEvent } from "../../server/event-queue.js" import type { Tabs } from "../tabs/index.js" import { cutArrayToFirstN } from "../utils/common.js" -import type { Terminal } from "./terminal/types.js" import type { TimelineEvent } from "./timeline/types.js" export const defaultServerRouteState: ServerRouteInfo = { @@ -28,7 +27,6 @@ export const ROUTE_BOUNDARY_GRADIENTS = { export const RouteBoundaryOptions = Object.keys(ROUTE_BOUNDARY_GRADIENTS) as (keyof typeof ROUTE_BOUNDARY_GRADIENTS)[] export type RouteWildcards = Record | undefined> -type TriggerPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle-left" | "middle-right" export type ServerRouteInfo = { actions?: Omit[] @@ -61,30 +59,7 @@ export type HTMLError = { export type ReactRouterDevtoolsState = { timeline: TimelineEvent[] - terminals: Terminal[] settings: { - /** - * Enables the bippy inspector to inspect react components - */ - enableInspector: boolean - /** - * The breakpoints to show in the corner so you can see the current breakpoint that you defined - */ - breakpoints: { name: string; min: number; max: number }[] - /** - * Whether to show the breakpoint indicator - */ - showBreakpointIndicator: boolean - /** - * The live urls to show in the corner which allow you to open the app in a different environment (eg. staging, production) - * @default [] - */ - liveUrls: { url: string; name: string }[] - /** - * The position of the live urls - * @default "bottom-left" - */ - liveUrlsPosition: "bottom-left" | "bottom-right" | "top-left" | "top-right" /** * The route boundary gradient color to use * @default "silver" @@ -97,32 +72,6 @@ export type ReactRouterDevtoolsState = { routeBoundaryGradient: keyof typeof ROUTE_BOUNDARY_GRADIENTS routeWildcards: RouteWildcards activeTab: Tabs - height: number - /** - * The maximum height of the panel - * @default 800 - */ - maxHeight: number - /** - * The minimum height of the panel - * @default 200 - */ - minHeight: number - /** - * Whether the dev tools should be open by default - * @default false - */ - defaultOpen: boolean - /** - * Whether the dev tools trigger should be hidden until the user hovers over it - * @default false - */ - hideUntilHover: boolean - /** - * The position of the trigger button - * @default "bottom-right" - */ - position: TriggerPosition /** * The initial expansion level of the JSON viewer objects * @default 1 @@ -131,27 +80,9 @@ export type ReactRouterDevtoolsState = { hoveredRoute: string isHoveringRoute: boolean routeViewMode: "list" | "tree" - /** - * The location of the panel once it is open - * @default "bottom" - */ - panelLocation: "top" | "bottom" + withServerDevTools: boolean - /** - * The hotkey to open the dev tools - * @default "shift+a" - */ - openHotkey: string - /** - * Whether to require the URL flag to open the dev tools - * @default false - */ - requireUrlFlag: boolean - /** - * The URL flag to open the dev tools, used in conjunction with requireUrlFlag (if set to true) - * @default "rdt" - */ - urlFlag: string + /** * Whether to show route boundaries on hover of the route segment or clicking a button */ @@ -160,52 +91,25 @@ export type ReactRouterDevtoolsState = { htmlErrors: HTMLError[] server?: ServerInfo persistOpen: boolean - detachedWindow: boolean - detachedWindowOwner: boolean } export const initialState: ReactRouterDevtoolsState = { timeline: [], - terminals: [{ id: 0, locked: false, output: [], history: [] }], server: undefined, settings: { - enableInspector: false, showRouteBoundariesOn: "click", - breakpoints: [ - { name: "", min: 0, max: 639 }, - { name: "sm", min: 640, max: 767 }, - { name: "md", min: 768, max: 1023 }, - { name: "lg", min: 1024, max: 1279 }, - { name: "xl", min: 1280, max: 1535 }, - { name: "2xl", min: 1536, max: 9999 }, - ], - showBreakpointIndicator: true, - liveUrls: [], - liveUrlsPosition: "bottom-left", editorName: "VSCode", routeBoundaryGradient: "watermelon", routeWildcards: {}, activeTab: "page", - height: 400, - maxHeight: 600, - minHeight: 200, - defaultOpen: false, - hideUntilHover: false, - position: "bottom-right", expansionLevel: 1, hoveredRoute: "", isHoveringRoute: false, routeViewMode: "tree", - panelLocation: "bottom", withServerDevTools: true, - openHotkey: "shift+a", - requireUrlFlag: false, - urlFlag: "rdt", }, htmlErrors: [], persistOpen: false, - detachedWindow: false, - detachedWindowOwner: false, } /** Reducer action types */ @@ -214,48 +118,6 @@ type SetTimelineEvent = { payload: TimelineEvent } -type ToggleTerminalLock = { - type: "TOGGLE_TERMINAL_LOCK" - payload: { - terminalId: Terminal["id"] - locked?: boolean - } -} - -type AddOrRemoveTerminal = { - type: "ADD_OR_REMOVE_TERMINAL" - payload?: Terminal["id"] -} - -type AddTerminalOutput = { - type: "ADD_TERMINAL_OUTPUT" - payload: { - terminalId: Terminal["id"] - output: Terminal["output"][number] - } -} - -type AddTerminalHistory = { - type: "ADD_TERMINAL_HISTORY" - payload: { - terminalId: Terminal["id"] - history: Terminal["history"][number] - } -} - -type ClearTerminalOutput = { - type: "CLEAR_TERMINAL_OUTPUT" - payload: Terminal["id"] -} - -type SetProcessId = { - type: "SET_PROCESS_ID" - payload: { - terminalId: Terminal["id"] - processId?: number - } -} - type SetDetachedWindowOwner = { type: "SET_DETACHED_WINDOW_OWNER" payload: boolean @@ -300,12 +162,6 @@ type SetHtmlErrors = { /** Aggregate of all action types */ export type ReactRouterDevtoolsActions = | SetTimelineEvent - | ToggleTerminalLock - | AddOrRemoveTerminal - | AddTerminalOutput - | ClearTerminalOutput - | AddTerminalHistory - | SetProcessId | PurgeTimeline | SetSettings | SetWholeState @@ -320,11 +176,6 @@ export const rdtReducer = ( { type, payload }: ReactRouterDevtoolsActions ): ReactRouterDevtoolsState => { switch (type) { - case "SET_DETACHED_WINDOW_OWNER": - return { - ...state, - detachedWindowOwner: payload, - } case "SET_HTML_ERRORS": return { ...state, @@ -368,96 +219,6 @@ export const rdtReducer = ( isSubmitted: true, } - case "SET_PROCESS_ID": - return { - ...state, - terminals: state.terminals.map((terminal) => { - if (terminal.id === payload.terminalId) { - return { - ...terminal, - processId: payload.processId, - } - } - return terminal - }), - } - case "TOGGLE_TERMINAL_LOCK": - return { - ...state, - terminals: state.terminals.map((terminal) => { - if (terminal.id === payload.terminalId) { - return { - ...terminal, - locked: payload.locked ?? !terminal.locked, - } - } - return terminal - }), - } - case "ADD_OR_REMOVE_TERMINAL": { - const terminalExists = state.terminals.some((terminal) => terminal.id === payload) - if (terminalExists) { - return { - ...state, - terminals: state.terminals - .filter((terminal) => terminal.id !== payload) - .map((terminal, i) => ({ ...terminal, id: i })), - } - } - return { - ...state, - terminals: [ - ...state.terminals, - { - id: state.terminals.length, - locked: false, - history: [], - output: [], - }, - ], - } - } - case "ADD_TERMINAL_OUTPUT": - return { - ...state, - terminals: state.terminals.map((terminal) => { - if (terminal.id === payload.terminalId) { - return { - ...terminal, - output: [...terminal.output, payload.output], - } - } - return terminal - }), - } - case "CLEAR_TERMINAL_OUTPUT": - return { - ...state, - terminals: state.terminals.map((terminal) => { - if (terminal.id === payload) { - return { - ...terminal, - output: [], - } - } - return terminal - }), - } - - case "ADD_TERMINAL_HISTORY": - return { - ...state, - terminals: state.terminals.map((terminal) => { - if (terminal.id === payload.terminalId) { - return { - ...terminal, - history: [...terminal.history, payload.history], - } - } - return terminal - }), - } - case "SET_PERSIST_OPEN": return { ...state, diff --git a/packages/react-router-devtools/src/client/context/terminal/types.ts b/packages/react-router-devtools/src/client/context/terminal/types.ts deleted file mode 100644 index f61bdfe7..00000000 --- a/packages/react-router-devtools/src/client/context/terminal/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -interface TerminalOutput { - type: "output" | "command" | "error" - value: string -} - -export interface Terminal { - id: number - locked: boolean - history: string[] - output: TerminalOutput[] - processId?: number -} diff --git a/packages/react-router-devtools/src/client/context/useRDTContext.ts b/packages/react-router-devtools/src/client/context/useRDTContext.ts index d4d16711..c0719d9c 100644 --- a/packages/react-router-devtools/src/client/context/useRDTContext.ts +++ b/packages/react-router-devtools/src/client/context/useRDTContext.ts @@ -61,28 +61,6 @@ export const useServerInfo = () => { return { server, setServerInfo } } -export const useDetachedWindowControls = () => { - const { state, dispatch } = useRDTContext() - const { detachedWindow, detachedWindowOwner } = state - - const setDetachedWindowOwner = useCallback( - (isDetachedWindowOwner: boolean) => { - dispatch({ - type: "SET_DETACHED_WINDOW_OWNER", - payload: isDetachedWindowOwner, - }) - }, - [dispatch] - ) - - return { - detachedWindow: detachedWindow || window.RDT_MOUNTED, - detachedWindowOwner, - setDetachedWindowOwner, - isDetached: detachedWindow || detachedWindowOwner, - } -} - export const useSettingsContext = () => { const { dispatch, state } = useRDTContext() const { settings } = state diff --git a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx index adf65843..d0b18582 100644 --- a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx @@ -1,8 +1,6 @@ import clsx from "clsx" import { useEffect, useState } from "react" -import { useLocation } from "react-router" import { RDTContextProvider } from "./context/RDTContext.js" -import { useSettingsContext } from "./context/useRDTContext.js" import { useReactTreeListeners } from "./hooks/useReactTreeListeners.js" import { useSetRouteBoundaries } from "./hooks/useSetRouteBoundaries.js" import { useTimelineHandler } from "./hooks/useTimelineHandler.js" @@ -20,20 +18,20 @@ const Embedded = ({ plugins: pluginArray, mainPanelClassName, className }: Embed useTimelineHandler() useReactTreeListeners() useSetRouteBoundaries() - const { settings } = useSettingsContext() - const { position } = settings - const leftSideOriented = position.includes("left") - const url = useLocation().search + const plugins = pluginArray?.map((plugin) => (typeof plugin === "function" ? plugin() : plugin)) - if (settings.requireUrlFlag && !url.includes(settings.urlFlag)) return null + return (
- +
) diff --git a/packages/react-router-devtools/src/client/hooks/detached/useCheckIfStillDetached.ts b/packages/react-router-devtools/src/client/hooks/detached/useCheckIfStillDetached.ts deleted file mode 100644 index 02b1d1aa..00000000 --- a/packages/react-router-devtools/src/client/hooks/detached/useCheckIfStillDetached.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { useCallback, useContext, useEffect, useState } from "react" -import { RDTContext, getExistingStateFromStorage } from "../../context/RDTContext.js" -import { - REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED, - REACT_ROUTER_DEV_TOOLS_DETACHED, - REACT_ROUTER_DEV_TOOLS_DETACHED_OWNER, - REACT_ROUTER_DEV_TOOLS_IS_DETACHED, - getBooleanFromStorage, - setStorageItem, -} from "../../utils/storage.js" - -export const useCheckIfStillDetached = () => { - const { dispatch } = useContext(RDTContext) - const [checking, setChecking] = useState(false) - const isDetached = getBooleanFromStorage(REACT_ROUTER_DEV_TOOLS_IS_DETACHED) - - useEffect(() => { - if (!checking || !isDetached) { - return - } - - // On reload the detached window will set the flag back to false so we can check if it is still detached - const isNotDetachedAnymore = getBooleanFromStorage(REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED) - // The window hasn't set it back to true so it is not detached anymore and we clean all the detached state - if (isNotDetachedAnymore) { - setStorageItem(REACT_ROUTER_DEV_TOOLS_IS_DETACHED, "false") - setStorageItem(REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED, "false") - sessionStorage.removeItem(REACT_ROUTER_DEV_TOOLS_DETACHED_OWNER) - sessionStorage.removeItem(REACT_ROUTER_DEV_TOOLS_DETACHED) - const state = getExistingStateFromStorage() - dispatch({ type: "SET_WHOLE_STATE", payload: state }) - setChecking(false) - } - }, [checking, dispatch, isDetached]) - - const checkDetachment = useCallback( - // biome-ignore lint/suspicious/noExplicitAny: we don't care about the event type - (e: any) => { - // We only care about the should_check key - if (e.key !== REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED) { - return - } - - const shouldCheckDetached = getBooleanFromStorage(REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED) - - // If the detached window is unloaded we want to check if it is still there - if (shouldCheckDetached && !checking) { - setTimeout(() => setChecking(true), 200) - } - }, - [checking] - ) - useEffect(() => { - if (checking || !isDetached) { - return - } - - addEventListener("storage", checkDetachment) - return () => removeEventListener("storage", checkDetachment) - }, [checking, isDetached, checkDetachment]) -} diff --git a/packages/react-router-devtools/src/client/hooks/detached/useListenToRouteChange.ts b/packages/react-router-devtools/src/client/hooks/detached/useListenToRouteChange.ts deleted file mode 100644 index cd78ce11..00000000 --- a/packages/react-router-devtools/src/client/hooks/detached/useListenToRouteChange.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { useEffect, useRef } from "react" -import { useLocation, useNavigate, useNavigation } from "react-router" -import { detachedModeSetup } from "../../context/RDTContext.js" -import { useDetachedWindowControls } from "../../context/useRDTContext.js" -import { getStorageItem, setStorageItem } from "../../utils/storage.js" -import { useAttachListener } from "../useAttachListener.js" - -const LOCAL_STORAGE_ROUTE_KEY = "rdt_route" - -export const setRouteInLocalStorage = (route: string) => setStorageItem(LOCAL_STORAGE_ROUTE_KEY, route) - -const getRouteFromLocalStorage = () => getStorageItem(LOCAL_STORAGE_ROUTE_KEY) - -export const useListenToRouteChange = () => { - const { detachedWindowOwner } = useDetachedWindowControls() - const location = useLocation() - const navigate = useNavigate() - const navigation = useNavigation() - const locationRoute = location.pathname + location.search - const navigationRoute = (navigation.location?.pathname ?? "") + (navigation.location?.search ?? "") - const ref = useRef(locationRoute) - const route = getRouteFromLocalStorage() - - // Used by the owner window only - // biome-ignore lint/correctness/useExhaustiveDependencies: investigate if needed - useEffect(() => { - const { detachedWindowOwner } = detachedModeSetup() - if (!detachedWindowOwner) { - return - } - // If the route changes and this is the original window store the event into local storage - if (route !== locationRoute) { - setRouteInLocalStorage(locationRoute) - } - }, [locationRoute, detachedWindowOwner, route]) - - // Used to sync the route between the routes - - // biome-ignore lint/suspicious/noExplicitAny: we don't care about the event type (should be fixed) - useAttachListener("storage", "window", (e: any) => { - // We only care about the key that changes the route - if (e.key !== LOCAL_STORAGE_ROUTE_KEY) { - return - } - - const route = getRouteFromLocalStorage() - - if (route && route !== ref.current && route !== navigationRoute && navigation.state === "idle") { - ref.current = route - navigate(route) - } - }) -} diff --git a/packages/react-router-devtools/src/client/hooks/detached/useRemoveBody.ts b/packages/react-router-devtools/src/client/hooks/detached/useRemoveBody.ts deleted file mode 100644 index 13fbbe79..00000000 --- a/packages/react-router-devtools/src/client/hooks/detached/useRemoveBody.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect } from "react" -import type { ReactRouterDevtoolsState } from "../../context/rdtReducer.js" -import { REACT_ROUTER_DEV_TOOLS } from "../../utils/storage.js" - -export const useRemoveBody = (state: ReactRouterDevtoolsState) => { - useEffect(() => { - if (!state.detachedWindow) { - return - } - - const elements = document.body.children - document.body.classList.add("bg-[#212121]") - for (let i = 0; i < elements.length; i++) { - const element = elements[i] - if (element.id !== REACT_ROUTER_DEV_TOOLS) { - element.classList.add("hidden") - } - } - }, [state]) -} diff --git a/packages/react-router-devtools/src/client/hooks/detached/useResetDetachmentCheck.ts b/packages/react-router-devtools/src/client/hooks/detached/useResetDetachmentCheck.ts deleted file mode 100644 index f2ae4587..00000000 --- a/packages/react-router-devtools/src/client/hooks/detached/useResetDetachmentCheck.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useDetachedWindowControls } from "../../context/useRDTContext.js" -import { REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED, setStorageItem } from "../../utils/storage.js" -import { useAttachListener } from "../useAttachListener.js" -import { useCheckIfStillDetached } from "./useCheckIfStillDetached.js" - -export const useResetDetachmentCheck = () => { - const { isDetached } = useDetachedWindowControls() - useCheckIfStillDetached() - useAttachListener("unload", "window", () => setStorageItem(REACT_ROUTER_DEV_TOOLS_CHECK_DETACHED, "true"), isDetached) -} diff --git a/packages/react-router-devtools/src/client/hooks/detached/useSyncStateWhenDetached.ts b/packages/react-router-devtools/src/client/hooks/detached/useSyncStateWhenDetached.ts deleted file mode 100644 index 96bf48f5..00000000 --- a/packages/react-router-devtools/src/client/hooks/detached/useSyncStateWhenDetached.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { getExistingStateFromStorage } from "../../context/RDTContext.js" -import { useRDTContext } from "../../context/useRDTContext.js" -import { REACT_ROUTER_DEV_TOOLS_SETTINGS, REACT_ROUTER_DEV_TOOLS_STATE } from "../../utils/storage.js" -import { useAttachListener } from "../useAttachListener.js" - -const refreshRequiredKeys = [REACT_ROUTER_DEV_TOOLS_SETTINGS, REACT_ROUTER_DEV_TOOLS_STATE] - -export const useSyncStateWhenDetached = () => { - const { dispatch, state } = useRDTContext() - - // biome-ignore lint/suspicious/noExplicitAny: this should be fixed - useAttachListener("storage", "window", (e: any) => { - // Not in detached mode - if (!state.detachedWindow && !state.detachedWindowOwner) { - return - } - // Not caused by the dev tools - if (!refreshRequiredKeys.includes(e.key)) { - return - } - // Check if the settings have not changed and early return - if (e.key === REACT_ROUTER_DEV_TOOLS_SETTINGS) { - const oldSettings = JSON.stringify(state.settings) - if (oldSettings === e.newValue) { - return - } - } - // Check if the state has not changed and early return - if (e.key === REACT_ROUTER_DEV_TOOLS_STATE) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { settings, ...rest } = state - const oldState = JSON.stringify(rest) - if (oldState === e.newValue) { - return - } - } - - // store new state - const newState = getExistingStateFromStorage() - dispatch({ type: "SET_WHOLE_STATE", payload: newState }) - }) -} diff --git a/packages/react-router-devtools/src/client/hooks/useResize.ts b/packages/react-router-devtools/src/client/hooks/useResize.ts deleted file mode 100644 index aa199ed1..00000000 --- a/packages/react-router-devtools/src/client/hooks/useResize.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { useCallback, useEffect, useState } from "react" -import { useSettingsContext } from "../context/useRDTContext.js" - -const useResize = () => { - const { setSettings, settings } = useSettingsContext() - const { height, maxHeight, minHeight, panelLocation } = settings - const [isResizing, setIsResizing] = useState(false) - - // biome-ignore lint/correctness/useExhaustiveDependencies: - const enableResize = useCallback(() => { - setIsResizing(true) - }, [setIsResizing]) - - // biome-ignore lint/correctness/useExhaustiveDependencies: - const disableResize = useCallback(() => { - setIsResizing(false) - }, [setIsResizing]) - - const resize = useCallback( - (e: MouseEvent) => { - if (isResizing) { - window.getSelection()?.removeAllRanges() // Prevent text selection - const newHeight = panelLocation === "top" ? e.clientY : window.innerHeight - e.clientY // Calculate the new height based on the mouse position - - //const newHeight = e.clientY; // You may want to add some offset here from props - - if (newHeight > maxHeight) { - setSettings({ height: maxHeight }) - return - } - - if (newHeight < minHeight) { - setSettings({ height: minHeight }) - return - } - - setSettings({ height: newHeight }) - } - }, - [isResizing, maxHeight, minHeight, setSettings, panelLocation] - ) - - useEffect(() => { - document.addEventListener("mousemove", resize) - document.addEventListener("mouseup", disableResize) - - return () => { - document.removeEventListener("mousemove", resize) - document.removeEventListener("mouseup", disableResize) - } - }, [disableResize, resize]) - - return { height, enableResize, disableResize, isResizing } -} - -export { useResize } diff --git a/packages/react-router-devtools/src/client/hooks/useSetRouteBoundaries.ts b/packages/react-router-devtools/src/client/hooks/useSetRouteBoundaries.ts index b0ebd391..51444567 100644 --- a/packages/react-router-devtools/src/client/hooks/useSetRouteBoundaries.ts +++ b/packages/react-router-devtools/src/client/hooks/useSetRouteBoundaries.ts @@ -1,14 +1,13 @@ import { useCallback, useEffect } from "react" import { useMatches } from "react-router" import { ROUTE_BOUNDARY_GRADIENTS } from "../context/rdtReducer.js" -import { useDetachedWindowControls, useSettingsContext } from "../context/useRDTContext.js" +import { useSettingsContext } from "../context/useRDTContext.js" import { useAttachListener } from "./useAttachListener.js" import { ROUTE_CLASS } from "./useReactTreeListeners.js" export const useSetRouteBoundaries = () => { const matches = useMatches() const { settings, setSettings } = useSettingsContext() - const { detachedWindow } = useDetachedWindowControls() const applyOrRemoveClasses = useCallback( (isHovering?: boolean) => { // Overrides the hovering so the classes are force removed if needed @@ -40,9 +39,7 @@ export const useSetRouteBoundaries = () => { return } applyOrRemoveClasses() - if (!detachedWindow) { - return - } + setSettings({ isHoveringRoute: false, }) @@ -53,9 +50,7 @@ export const useSetRouteBoundaries = () => { return } applyOrRemoveClasses(false) - if (!detachedWindow) { - return - } + setSettings({ isHoveringRoute: false, }) @@ -65,7 +60,7 @@ export const useSetRouteBoundaries = () => { useEffect(() => { if (!settings.isHoveringRoute && !settings.hoveredRoute) return applyOrRemoveClasses() - if (!settings.isHoveringRoute && !detachedWindow) { + if (!settings.isHoveringRoute) { setSettings({ hoveredRoute: "", isHoveringRoute: false, @@ -76,7 +71,6 @@ export const useSetRouteBoundaries = () => { settings.isHoveringRoute, settings.routeBoundaryGradient, applyOrRemoveClasses, - detachedWindow, setSettings, ]) } diff --git a/packages/react-router-devtools/src/client/hooks/useTimelineHandler.ts b/packages/react-router-devtools/src/client/hooks/useTimelineHandler.ts index 52fd2569..346d67a2 100644 --- a/packages/react-router-devtools/src/client/hooks/useTimelineHandler.ts +++ b/packages/react-router-devtools/src/client/hooks/useTimelineHandler.ts @@ -1,7 +1,7 @@ import { useEffect, useRef } from "react" import { useActionData, useFetchers, useNavigation } from "react-router" import type { TimelineEvent } from "../context/timeline/types.js" -import { useDetachedWindowControls, useTimelineContext } from "../context/useRDTContext.js" +import { useTimelineContext } from "../context/useRDTContext.js" const uniqueId = () => (Math.random() * Date.now()).toString() @@ -57,12 +57,7 @@ const useTimelineHandler = () => { const navigationEventQueue = useRef([]) const { setTimelineEvent } = useTimelineContext() const responseData = useActionData() - const { detachedWindow } = useDetachedWindowControls() useEffect(() => { - // Do not record events if the window is detached, the main window will handle it - if (detachedWindow) { - return - } const { state, location, formAction, formData, formMethod, formEncType } = navigation if (state === "idle") { @@ -134,7 +129,7 @@ const useTimelineHandler = () => { }) return } - }, [navigation, responseData, setTimelineEvent, detachedWindow]) + }, [navigation, responseData, setTimelineEvent]) const fetcherEventQueue = useRef([]) // Fetchers handler diff --git a/packages/react-router-devtools/src/client/init/root.tsx b/packages/react-router-devtools/src/client/init/root.tsx index d7849cce..91c8c30e 100644 --- a/packages/react-router-devtools/src/client/init/root.tsx +++ b/packages/react-router-devtools/src/client/init/root.tsx @@ -1,22 +1,10 @@ -import { useEffect, useState } from "react" -import { createPortal } from "react-dom" +import { TanStackDevtools } from "@tanstack/react-devtools" import type { RdtClientConfig } from "../context/RDTContext.js" import { RequestProvider } from "../context/requests/request-context.js" -import { ReactRouterDevTools, type ReactRouterDevtoolsProps } from "../react-router-dev-tools.js" +import { EmbeddedDevTools } from "../embedded-dev-tools.js" +import type { ReactRouterDevtoolsProps } from "../react-router-dev-tools.js" import { hydrationDetector } from "./hydration.js" - -let hydrating = true - -function useHydrated() { - const [hydrated, setHydrated] = useState(() => !hydrating) - - useEffect(function hydrate() { - hydrating = false - setHydrated(true) - }, []) - - return hydrated -} +import triggerImage from "./trigger.svg" export const defineClientConfig = (config: RdtClientConfig) => config @@ -26,21 +14,19 @@ export const defineClientConfig = (config: RdtClientConfig) => config */ // biome-ignore lint/suspicious/noExplicitAny: we don't know or care about props type -export const withViteDevTools = (Component: any, config?: ReactRouterDevtoolsProps) => (props: any) => { +export const withViteDevTools = (Component: any, _config?: ReactRouterDevtoolsProps) => (props: any) => { hydrationDetector() // biome-ignore lint/suspicious/noExplicitAny: we don't care about the type here as we spread it below function AppWithDevTools(props: any) { - const hydrated = useHydrated() - if (!hydrated) - return ( - - - - ) return ( - {createPortal(, document.body)} + }]} + /> ) } diff --git a/packages/react-router-devtools/src/client/components/Logo.tsx b/packages/react-router-devtools/src/client/init/trigger.svg similarity index 79% rename from packages/react-router-devtools/src/client/components/Logo.tsx rename to packages/react-router-devtools/src/client/init/trigger.svg index f315d92d..392e7323 100644 --- a/packages/react-router-devtools/src/client/components/Logo.tsx +++ b/packages/react-router-devtools/src/client/init/trigger.svg @@ -1,31 +1,19 @@ -import type { SVGProps } from "react" - -interface LogoProps extends SVGProps { - className?: string -} - -const Logo = ({ className, style }: LogoProps) => { - return ( - - Logo - - - - - - ) -} - -export { Logo } + + Logo + + + + + \ No newline at end of file diff --git a/packages/react-router-devtools/src/client/layout/ContentPanel.tsx b/packages/react-router-devtools/src/client/layout/ContentPanel.tsx index 48be792d..8e3a277b 100644 --- a/packages/react-router-devtools/src/client/layout/ContentPanel.tsx +++ b/packages/react-router-devtools/src/client/layout/ContentPanel.tsx @@ -5,7 +5,6 @@ import { TimelineTab } from "../tabs/TimelineTab.js" import type { Tab } from "../tabs/index.js" interface ContentPanelProps { - leftSideOriented: boolean plugins?: Tab[] } diff --git a/packages/react-router-devtools/src/client/layout/MainPanel.tsx b/packages/react-router-devtools/src/client/layout/MainPanel.tsx index c7feb5d7..50b3844c 100644 --- a/packages/react-router-devtools/src/client/layout/MainPanel.tsx +++ b/packages/react-router-devtools/src/client/layout/MainPanel.tsx @@ -1,9 +1,4 @@ import clsx from "clsx" -import { useState } from "react" -import { useDetachedWindowControls, useSettingsContext } from "../context/useRDTContext.js" -import { useAttachWindowListener } from "../hooks/useAttachListener.js" -import { useDebounce } from "../hooks/useDebounce.js" -import { useResize } from "../hooks/useResize.js" interface MainPanelProps { children: React.ReactNode @@ -12,54 +7,21 @@ interface MainPanelProps { className?: string } -const useResizeDetachedPanel = () => { - const { isDetached } = useDetachedWindowControls() - const [state, setState] = useState(0) - const debounce = useDebounce(() => { - setState(state + 1) - }) - useAttachWindowListener("resize", debounce, isDetached) -} - -const MainPanel = ({ children, isOpen, isEmbedded = false, className }: MainPanelProps) => { - const { settings } = useSettingsContext() - const { detachedWindow } = useDetachedWindowControls() - const { height, panelLocation } = settings - const { enableResize, disableResize, isResizing } = useResize() - useResizeDetachedPanel() - +const MainPanel = ({ children, isOpen, className }: MainPanelProps) => { return (
- {panelLocation === "bottom" && !isEmbedded && ( -
- )} {children} - {panelLocation === "top" && ( -
- )}
) } diff --git a/packages/react-router-devtools/src/client/layout/Tabs.tsx b/packages/react-router-devtools/src/client/layout/Tabs.tsx index 9dfbe3dc..d8fce465 100644 --- a/packages/react-router-devtools/src/client/layout/Tabs.tsx +++ b/packages/react-router-devtools/src/client/layout/Tabs.tsx @@ -1,20 +1,8 @@ import clsx from "clsx" -import { Icon } from "../components/icon/Icon.js" -import { - useDetachedWindowControls, - useHtmlErrors, - usePersistOpen, - useSettingsContext, -} from "../context/useRDTContext.js" +import { useHtmlErrors, useSettingsContext } from "../context/useRDTContext.js" import { useHorizontalScroll } from "../hooks/useHorizontalScroll.js" import { useTabs } from "../hooks/useTabs.js" import type { Tab as TabType, Tabs as TabsType } from "../tabs/index.js" -import { - REACT_ROUTER_DEV_TOOLS_DETACHED_OWNER, - REACT_ROUTER_DEV_TOOLS_IS_DETACHED, - setSessionItem, - setStorageItem, -} from "../utils/storage.js" declare global { interface Window { @@ -64,28 +52,12 @@ const Tab = ({ ) } -const Tabs = ({ plugins, setIsOpen }: TabsProps) => { +const Tabs = ({ plugins }: TabsProps) => { const { settings } = useSettingsContext() const { htmlErrors } = useHtmlErrors() - const { setPersistOpen } = usePersistOpen() const { activeTab } = settings const { visibleTabs } = useTabs(plugins) const scrollRef = useHorizontalScroll() - const { setDetachedWindowOwner, detachedWindowOwner, detachedWindow } = useDetachedWindowControls() - const handleDetachment = () => { - const rdtWindow = window.open( - window.location.href, - "", - `popup,width=${window.innerWidth},height=${settings.height},top=${window.screen.height},left=${window.screenLeft}}` - ) - - if (rdtWindow) { - setDetachedWindowOwner(true) - setStorageItem(REACT_ROUTER_DEV_TOOLS_IS_DETACHED, "true") - setSessionItem(REACT_ROUTER_DEV_TOOLS_DETACHED_OWNER, "true") - rdtWindow.RDT_MOUNTED = true - } - } const getErrorCount = () => { return htmlErrors.length + (window.HYDRATION_OVERLAY?.ERROR ? 1 : 0) @@ -112,38 +84,6 @@ const Tabs = ({ plugins, setIsOpen }: TabsProps) => { )} /> ))} -
- {!detachedWindow && setIsOpen && ( - <> - {!detachedWindowOwner && ( - , - id: "detach", - name: "Detach", - hideTimeline: false, - component: <>, - }} - /> - )} - , - id: "close", - name: "Close", - hideTimeline: false, - component: <>, - }} - onClick={() => { - setPersistOpen(false) - setIsOpen(false) - }} - /> - - )} -
) diff --git a/packages/react-router-devtools/src/client/react-router-dev-tools.tsx b/packages/react-router-devtools/src/client/react-router-dev-tools.tsx index 1840af42..f090cb94 100644 --- a/packages/react-router-devtools/src/client/react-router-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/react-router-dev-tools.tsx @@ -1,130 +1,10 @@ -import { useEffect, useState } from "react" -import { useLocation } from "react-router" -import { Trigger } from "./components/Trigger.js" -import { RDTContextProvider, type RdtClientConfig } from "./context/RDTContext.js" -import { useDetachedWindowControls, usePersistOpen, useSettingsContext } from "./context/useRDTContext.js" -import { useResetDetachmentCheck } from "./hooks/detached/useResetDetachmentCheck.js" -import { useSyncStateWhenDetached } from "./hooks/detached/useSyncStateWhenDetached.js" -import { useReactTreeListeners } from "./hooks/useReactTreeListeners.js" -import { useSetRouteBoundaries } from "./hooks/useSetRouteBoundaries.js" -import { useTimelineHandler } from "./hooks/useTimelineHandler.js" -import { ContentPanel } from "./layout/ContentPanel.js" -import { MainPanel } from "./layout/MainPanel.js" -import { Tabs } from "./layout/Tabs.js" +import type { RdtClientConfig } from "./context/RDTContext.js" import type { Tab } from "./tabs/index.js" -import { - REACT_ROUTER_DEV_TOOLS, - REACT_ROUTER_DEV_TOOLS_DETACHED_OWNER, - REACT_ROUTER_DEV_TOOLS_IS_DETACHED, - setSessionItem, - setStorageItem, -} from "./utils/storage.js" import "../input.css" -/* import Inspector from "bippy/experiments/inspect" */ -import { useHotkeys } from "react-hotkeys-hook" import type { RdtPlugin } from "../index.js" -import { Breakpoints } from "./components/Breakpoints.js" -import { LiveUrls } from "./components/LiveUrls.js" -import { useListenToRouteChange } from "./hooks/detached/useListenToRouteChange.js" -import { useDebounce } from "./hooks/useDebounce.js" -import { useDevServerConnection } from "./hooks/useDevServerConnection.js" -import { useOpenElementSource } from "./hooks/useOpenElementSource.js" -const recursivelyChangeTabIndex = (node: Element | HTMLElement, remove = true) => { - if (remove) { - node.setAttribute("tabIndex", "-1") - } else { - node.removeAttribute("tabIndex") - } - for (const child of node.children) { - recursivelyChangeTabIndex(child, remove) - } -} - -const DevTools = ({ plugins: pluginArray }: ReactRouterDevtoolsProps) => { - useTimelineHandler() - useResetDetachmentCheck() - useReactTreeListeners() - useSetRouteBoundaries() - useSyncStateWhenDetached() - useDevServerConnection() - useOpenElementSource() - useListenToRouteChange() - - const { setPersistOpen } = usePersistOpen() - const url = useLocation().search - const { detachedWindowOwner, isDetached, setDetachedWindowOwner } = useDetachedWindowControls() - const { settings } = useSettingsContext() - const { persistOpen } = usePersistOpen() - const { position } = settings - const [isOpen, setIsOpen] = useState(isDetached || settings.defaultOpen || persistOpen) - const leftSideOriented = position.includes("left") - const plugins = pluginArray?.map((plugin) => (typeof plugin === "function" ? plugin() : plugin)) - const debounceSetOpen = useDebounce(() => { - setIsOpen(!isOpen) - setPersistOpen(!isOpen) - }, 100) - useHotkeys(settings.openHotkey, () => debounceSetOpen()) - useHotkeys("esc", () => (isOpen ? debounceSetOpen() : null)) - - useEffect(() => { - const el = document.getElementById(REACT_ROUTER_DEV_TOOLS) - if (!el) return - recursivelyChangeTabIndex(el, !isOpen) - }, [isOpen]) - - if (settings.requireUrlFlag && !url.includes(settings.urlFlag)) return null - // If the dev tools are detached, we don't want to render the main panel - if (detachedWindowOwner) { - return ( -
- { - setDetachedWindowOwner(false) - setStorageItem(REACT_ROUTER_DEV_TOOLS_IS_DETACHED, "false") - setSessionItem(REACT_ROUTER_DEV_TOOLS_DETACHED_OWNER, "false") - }} - /> -
- ) - } - - return ( -
- - - - {/* */} - -
- - -
-
-
- ) -} export interface ReactRouterDevtoolsProps { // Additional tabs to add to the dev tools plugins?: (Tab | RdtPlugin)[] config?: RdtClientConfig } - -const ReactRouterDevTools = ({ plugins, config }: ReactRouterDevtoolsProps) => { - return ( - - - - ) -} - -export { ReactRouterDevTools } diff --git a/packages/react-router-devtools/src/client/tabs/PageTab.tsx b/packages/react-router-devtools/src/client/tabs/PageTab.tsx index 743b6bb5..d836fb66 100644 --- a/packages/react-router-devtools/src/client/tabs/PageTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/PageTab.tsx @@ -30,7 +30,7 @@ const PageTab = () => {
    - {routes.map((route, i) => ( + {routes.toReversed().map((route, i) => ( ))}
diff --git a/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx b/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx index a31b04d8..0a2e059f 100644 --- a/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx @@ -2,8 +2,7 @@ import { type MouseEvent, useEffect, useState } from "react" import { useMatches, useNavigate } from "react-router" import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../components/Accordion.js" import { NewRouteForm } from "../components/NewRouteForm.js" -import { useDetachedWindowControls, useSettingsContext } from "../context/useRDTContext.js" -import { setRouteInLocalStorage } from "../hooks/detached/useListenToRouteChange.js" +import { useSettingsContext } from "../context/useRDTContext.js" import { type ExtendedRoute, constructRoutePath, createExtendedRoutes } from "../utils/routing.js" import { createRouteTree } from "../utils/sanitize.js" @@ -19,7 +18,6 @@ const RoutesTab = () => { const activeRoutes = matches.map((match) => match.id) const { settings } = useSettingsContext() const { routeWildcards, routeViewMode } = settings - const { detachedWindow } = useDetachedWindowControls() const [activeRoute, setActiveRoute] = useState(null) const [routes] = useState(createExtendedRoutes() as ExtendedRoute[]) const [treeRoutes, setTreeRoutes] = useState(createRouteTree(window.__reactRouterManifest?.routes)) @@ -27,9 +25,6 @@ const RoutesTab = () => { const openNewRoute = (path: string) => (e?: MouseEvent) => { e?.preventDefault() navigate(path) - if (detachedWindow) { - setRouteInLocalStorage(path) - } } useEffect(function fetchAllRoutesOnMount() { diff --git a/packages/react-router-devtools/src/client/tabs/SettingsTab.tsx b/packages/react-router-devtools/src/client/tabs/SettingsTab.tsx index 8dd0444e..41f4ca2f 100644 --- a/packages/react-router-devtools/src/client/tabs/SettingsTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/SettingsTab.tsx @@ -1,5 +1,4 @@ import { useState } from "react" -import { Checkbox } from "../components/Checkbox.js" import { Input } from "../components/Input.js" import { SelectWithOptions } from "../components/Select.js" import { Stack } from "../components/Stack.js" @@ -9,10 +8,7 @@ import { uppercaseFirstLetter } from "../utils/string.js" export const SettingsTab = () => { const { settings, setSettings } = useSettingsContext() - const [minHeight, setMinHeight] = useState(settings.minHeight.toString()) - const [maxHeight, setMaxHeight] = useState(settings.maxHeight.toString()) const [expansionLevel, setExpansionLevel] = useState(settings.expansionLevel.toString()) - const [openHotkey, setOpenHotkey] = useState(settings.openHotkey.toString()) return ( @@ -20,63 +16,9 @@ export const SettingsTab = () => { Settings
- setSettings({ defaultOpen: !settings.defaultOpen })} - value={settings.defaultOpen} - > - Open dev tools by default - - setSettings({ requireUrlFlag: !settings.requireUrlFlag })} - value={settings.requireUrlFlag} - > - Show dev tools only when URL flag is set ?{settings.urlFlag}=true - - setSettings({ hideUntilHover: !settings.hideUntilHover })} - value={settings.hideUntilHover} - > - Hide the trigger until hovered - - setSettings({ showBreakpointIndicator: !settings.showBreakpointIndicator })} - value={settings.showBreakpointIndicator} - > - Show breakpoint indicator - - {/* setSettings({ enableInspector: !settings.enableInspector })} - value={settings.enableInspector} - > - Enable react component inspector - */}
- {settings.requireUrlFlag && ( - setSettings({ urlFlag: e.target.value ?? "" })} - onBlur={(e) => { - setSettings({ urlFlag: e.target.value.trim() }) - }} - /> - )} - { } }} /> - setOpenHotkey(e.target.value ?? "")} - onBlur={(e) => { - const value = e.target.value - if (value) { - setSettings({ openHotkey: value }) - } - }} - /> -
- setMinHeight(e.target.value ?? "")} - onBlur={(e) => { - const value = Number.parseInt(e.target.value) - if (value && !Number.isNaN(value) && value < settings.maxHeight && value > 100) { - setSettings({ minHeight: value }) - } - }} - /> - setMaxHeight(e.target.value ?? "")} - onBlur={(e) => { - const value = Number.parseInt(e.target.value) - if (value && !Number.isNaN(value) && value > settings.minHeight) { - setSettings({ maxHeight: value }) - } - }} - /> -
-
- setSettings({ position: value })} - value={settings.position} - className="w-full" - options={[ - { label: "Bottom Right", value: "bottom-right" }, - { label: "Bottom Left", value: "bottom-left" }, - { label: "Top Right", value: "top-right" }, - { label: "Top Left", value: "top-left" }, - { label: "Middle Right", value: "middle-right" }, - { label: "Middle Left", value: "middle-left" }, - ]} - hint="This will determine where your trigger position on the screen is when the tools are collapsed." - /> - setSettings({ liveUrlsPosition: value })} - value={settings.liveUrlsPosition} - className="w-full" - options={[ - { label: "Bottom Right", value: "bottom-right" }, - { label: "Bottom Left", value: "bottom-left" }, - { label: "Top Right", value: "top-right" }, - { label: "Top Left", value: "top-left" }, - ]} - hint="This will determine where your environments position on the screen is." - /> - setSettings({ panelLocation: value })} - value={settings.panelLocation} - className="w-full" - options={[ - { label: "Top", value: "top" }, - { label: "Bottom", value: "bottom" }, - ]} - hint="This will determine where your panel shows up once opened" - /> -
Plugin[] = ( ...args?.client, editorName: args?.editor?.name, } - const enhancedLogs = args?.enhancedLogs ?? true + const includeClient = args?.includeInProd?.client ?? false const includeServer = args?.includeInProd?.server ?? false const includeDevtools = args?.includeInProd?.devTools ?? false @@ -99,19 +98,8 @@ export const reactRouterDevTools: (args?: ReactRouterViteConfig) => Plugin[] = ( process.rdt_config = serverConfig } return [ - { - enforce: "pre", - name: "react-router-devtools:inject-source", - apply(config) { - return config.mode === "development" - }, - transform(code, id) { - if (id.includes("node_modules") || id.includes("?raw") || id.includes("dist") || id.includes("build")) - return code + ...devtools(), - return addSourceToJsx(code, id) - }, - }, { name: "react-router-devtools", apply(config) { @@ -378,51 +366,5 @@ export const reactRouterDevTools: (args?: ReactRouterViteConfig) => Plugin[] = ( } }, }, - { - name: "react-router-devtools:better-console-logs", - enforce: "pre", - apply(config) { - return config.mode === "development" && enhancedLogs - }, - async transform(code, id) { - // Ignore anything external - if ( - id.includes("node_modules") || - id.includes("?raw") || - id.includes("dist") || - id.includes("build") || - !id.includes(appDirName) - ) - return - - if (code.includes("console.")) { - const lines = code.split("\n") - return lines - .map((line, lineNumber) => { - if (line.trim().startsWith("//") || line.trim().startsWith("/**") || line.trim().startsWith("*")) { - return line - } - // Do not add for arrow functions or return statements - if (line.replaceAll(" ", "").includes("=>console.") || line.includes("return console.")) { - return line - } - - const column = line.indexOf("console.") - const location = `${id.replace(normalizePath(process.cwd()), "")}:${lineNumber + 1}:${column + 1}` - const logMessage = `'${chalk.magenta("LOG")} ${chalk.blueBright(`${location} - http://localhost:${port}/_rrdt/open-source?source=${encodeURIComponent(id.replace(normalizePath(process.cwd()), ""))}&line=${lineNumber + 1}&column=${column + 1}`)}\\n → '` - if (line.includes("console.log(")) { - const newLine = `console.log(${logMessage},` - return line.replace("console.log(", newLine) - } - if (line.includes("console.error(")) { - const newLine = `console.error(${logMessage},` - return line.replace("console.error(", newLine) - } - return line - }) - .join("\n") - } - }, - }, ] } diff --git a/packages/react-router-devtools/tailwind.config.js b/packages/react-router-devtools/tailwind.config.js index 067976c5..1e5873dd 100644 --- a/packages/react-router-devtools/tailwind.config.js +++ b/packages/react-router-devtools/tailwind.config.js @@ -4,8 +4,8 @@ export default { theme: { extend: { colors: { - popover: "#212121", - main: "#212121", + popover: "#191c24", + main: "#191c24", "popover-foreground": "#fff", }, keyframes: { diff --git a/packages/react-router-devtools/tsup-client.config.ts b/packages/react-router-devtools/tsup-client.config.ts index b07a2167..ea0f3166 100644 --- a/packages/react-router-devtools/tsup-client.config.ts +++ b/packages/react-router-devtools/tsup-client.config.ts @@ -8,4 +8,7 @@ export default defineConfig({ dts: true, format: ["esm"], external: ["react"], + loader: { + ".svg": "dataurl", + }, }) diff --git a/packages/react-router-devtools/tsup.config.ts b/packages/react-router-devtools/tsup.config.ts index 87abce49..f40cb102 100644 --- a/packages/react-router-devtools/tsup.config.ts +++ b/packages/react-router-devtools/tsup.config.ts @@ -8,4 +8,7 @@ export default defineConfig({ dts: true, format: ["esm"], external: ["vite-node"], + loader: { + ".svg": "dataurl", + }, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 343a7a85..e7044fe9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + react-router-devtools: workspace:* + importers: .: @@ -187,8 +190,8 @@ importers: specifier: 1.3.0 version: 1.3.0 react-router-devtools: - specifier: '*' - version: 5.1.3(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)) + specifier: workspace:* + version: link:../packages/react-router-devtools tailwindcss: specifier: 4.0.9 version: 4.0.9 @@ -244,6 +247,12 @@ importers: '@radix-ui/react-select': specifier: ^2.1.5 version: 2.2.6(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/devtools-vite': + specifier: ^0.3.8 + version: 0.3.8(vite@6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)) + '@tanstack/react-devtools': + specifier: ^0.7.7 + version: 0.7.7(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(csstype@3.1.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.9) '@types/react': specifier: '>=17' version: 19.2.0 @@ -294,14 +303,14 @@ importers: version: 3.0.1 devDependencies: '@react-router/dev': - specifier: ^7.5.3 - version: 7.9.3(@react-router/serve@7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3))(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@1.21.7)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1) + specifier: 7.5.3 + version: 7.5.3(@react-router/serve@7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3))(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@1.21.7)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1) '@react-router/node': - specifier: ^7.5.3 - version: 7.9.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + specifier: 7.5.3 + version: 7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) '@react-router/serve': - specifier: 7.1.4 - version: 7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + specifier: 7.5.3 + version: 7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.1 @@ -446,8 +455,8 @@ importers: specifier: 16.1.0 version: 16.1.0(postcss@8.5.6) react-router-devtools: - specifier: '*' - version: 5.0.4(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)) + specifier: workspace:* + version: link:../../packages/react-router-devtools tailwindcss: specifier: ^4.1.4 version: 4.1.14 @@ -498,8 +507,8 @@ importers: specifier: ^9.19.0 version: 9.37.0(jiti@2.6.1) react-router-devtools: - specifier: '*' - version: 5.1.3(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)) + specifier: workspace:* + version: link:../../packages/react-router-devtools typescript: specifier: ^5.8.3 version: 5.9.3 @@ -610,6 +619,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-jsx@7.27.1': resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} @@ -1853,6 +1868,24 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@react-router/dev@7.5.3': + resolution: {integrity: sha512-U+n8JYAREKg6eHIAXCjazsYlwPo/vcAbShpqePnDBUdDnePBwZ2JmoqhWV+7tIhyHvvHGQKlw6BcrSZtF549WQ==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@react-router/serve': ^7.5.3 + react-router: ^7.5.3 + typescript: ^5.1.0 + vite: ^5.1.0 || ^6.0.0 + wrangler: ^3.28.2 || ^4.0.0 + peerDependenciesMeta: + '@react-router/serve': + optional: true + typescript: + optional: true + wrangler: + optional: true + '@react-router/dev@7.9.3': resolution: {integrity: sha512-oPaO+OpvCo/rNTJrRipHSp31/K4It19PE5A24x21FlYlemPTe3fbGX/kyC2+8au/abXbvzNHfRbuIBD/rfojmA==} engines: {node: '>=20.0.0'} @@ -1885,6 +1918,17 @@ packages: typescript: optional: true + '@react-router/express@7.5.3': + resolution: {integrity: sha512-/fPrmeJQME7nL71FyUAMRGZk1PsrW1+hPMs7caIATmHKvE8hArd2BrpdsHEbGNvirnyO+qABQJmRFdNtCU/axQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + express: ^4.17.1 || ^5 + react-router: 7.5.3 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + '@react-router/express@7.9.3': resolution: {integrity: sha512-XNVj/8AfecE1n61bXD41LqpXAixyWBpmBWkrzVA2iG+SrQOb+J6TjqZYEmZmoqJHuHmkOjt6/Iz1f81p93peGQ==} engines: {node: '>=20.0.0'} @@ -1916,6 +1960,16 @@ packages: typescript: optional: true + '@react-router/node@7.5.3': + resolution: {integrity: sha512-w85YL6UngvhxGmgTBL3qwlVLFiA1EzNyG5S55qGcnhDikfb9z84gqMlTU4UqlZm8PjQ021HPTTN6I3kd7QE5sg==} + engines: {node: '>=20.0.0'} + peerDependencies: + react-router: 7.5.3 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + '@react-router/node@7.9.3': resolution: {integrity: sha512-+OvWxPPUgouOshw85QlG0J6yFJM0GMCCpXqPj38IcveeFLlP7ppOAEkOi7RBFrDvg7vSUtCEBDnsbuDCvxUPJg==} engines: {node: '>=20.0.0'} @@ -1933,6 +1987,13 @@ packages: peerDependencies: react-router: 7.1.4 + '@react-router/serve@7.5.3': + resolution: {integrity: sha512-0YkoVAJWAMtYPKQVXKb1RoSfy3EbjyzEeaFCL4twB4eB5Rj4MSE9uH0Zb9caNQXpq/8MDzjbe3SuvQ8uqwyqkQ==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + react-router: 7.5.3 + '@remix-run/node-fetch-server@0.9.0': resolution: {integrity: sha512-SoLMv7dbH+njWzXnOY6fI08dFMI5+/dQ+vY3n8RnnbdG7MdJEgiP28Xj/xWlnRnED/aB6SFw56Zop+LbmaaKqA==} @@ -2082,6 +2143,36 @@ packages: engines: {node: '>=8.10'} hasBin: true + '@solid-primitives/event-listener@2.4.3': + resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/keyboard@1.3.3': + resolution: {integrity: sha512-9dQHTTgLBqyAI7aavtO+HnpTVJgWQA1ghBSrmLtMu1SMxLPDuLfuNr+Tk5udb4AL4Ojg7h9JrKOGEEDqsJXWJA==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/resize-observer@2.1.3': + resolution: {integrity: sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/rootless@1.5.2': + resolution: {integrity: sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/static-store@0.1.2': + resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/utils@6.3.2': + resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} + peerDependencies: + solid-js: ^1.6.12 + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -2251,6 +2342,45 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@tanstack/devtools-client@0.0.3': + resolution: {integrity: sha512-kl0r6N5iIL3t9gGDRAv55VRM3UIyMKVH83esRGq7xBjYsRLe/BeCIN2HqrlJkObUXQMKhy7i8ejuGOn+bDqDBw==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-bus@0.3.2': + resolution: {integrity: sha512-yJT2As/drc+Epu0nsqCsJaKaLcaNGufiNxSlp/+/oeTD0jsBxF9/PJBfh66XVpYXkKr97b8689mSu7QMef0Rrw==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-client@0.3.3': + resolution: {integrity: sha512-RfV+OPV/M3CGryYqTue684u10jUt55PEqeBOnOtCe6tAmHI9Iqyc8nHeDhWPEV9715gShuauFVaMc9RiUVNdwg==} + engines: {node: '>=18'} + + '@tanstack/devtools-ui@0.4.3': + resolution: {integrity: sha512-7QshnQIHifURyMwl/qmYm4KDpsf8UJrJ8BUu+YvPx35RJBe2EO5qHPsefzWh6MlG/dUdVMBxP9nPqchESyuNFg==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/devtools-vite@0.3.8': + resolution: {integrity: sha512-Lenpim4NFcgeOQckbtcDYelsQRoplA87DA56PJHlpXNeAOjSxcBeBQElPS90WMGJ8tVDBMKuttEAI8NUDHSuzw==} + engines: {node: '>=18'} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 + + '@tanstack/devtools@0.6.21': + resolution: {integrity: sha512-j8cCmrOz7wu4G4jJ2ZZCo3fIGGDMygSQVPZDtyFylKtKC5i88Hnu6YioODP6I+0mbn9Qvr4eWgPHEONXAViXeA==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/react-devtools@0.7.7': + resolution: {integrity: sha512-mJ7Ixa+AadGF1b13tLkC8lX0JrM7CrH/SJMOqcCWot9l80KZCWeFnDF1+Ww25QosVbZ1db611LNcgsGz8pv3Zg==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8' + '@types/react-dom': '>=16.8' + react: '>=16.8' + react-dom: '>=16.8' + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -2902,6 +3032,10 @@ packages: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -3731,20 +3865,6 @@ packages: react-dom: optional: true - framer-motion@12.23.22: - resolution: {integrity: sha512-ZgGvdxXCw55ZYvhoZChTlG6pUuehecgvEAJz0BHoC5pQKW1EC5xf1Mul1ej5+ai+pVY0pylyFfdl45qnM1/GsA==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true - fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -3759,6 +3879,10 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -3877,6 +4001,11 @@ packages: globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + goober@2.1.18: + resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} + peerDependencies: + csstype: ^3.0.10 + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -4381,6 +4510,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -4404,6 +4536,9 @@ packages: resolution: {integrity: sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==} engines: {node: '>=18'} + launch-editor@2.11.1: + resolution: {integrity: sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg==} + lefthook-darwin-arm64@1.13.6: resolution: {integrity: sha512-m6Lb77VGc84/Qo21Lhq576pEvcgFCnvloEiP02HbAHcIXD0RTLy9u2yAInrixqZeaz13HYtdDaI7OBYAAdVt8A==} cpu: [arm64] @@ -4922,15 +5057,9 @@ packages: motion-dom@11.18.1: resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==} - motion-dom@12.23.21: - resolution: {integrity: sha512-5xDXx/AbhrfgsQmSE7YESMn4Dpo6x5/DTZ4Iyy4xqDvVHWvFVoV+V2Ri2S/ksx+D40wrZ7gPYiMWshkdoqNgNQ==} - motion-utils@11.18.1: resolution: {integrity: sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==} - motion-utils@12.23.6: - resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -5569,26 +5698,6 @@ packages: '@types/react': optional: true - react-router-devtools@5.0.4: - resolution: {integrity: sha512-iTWKNOOPZYMH6pYCoPc0aOFu0F5uVHc//Ugo90SRFqajPf4GRM5jFvrlmvNvxC98yp3ceJDit6Hargml9JpLtA==} - peerDependencies: - '@types/react': '>=17' - '@types/react-dom': '>=17' - react: '>=17' - react-dom: '>=17' - react-router: '>=7.0.0' - vite: '>=5.0.0 || >=6.0.0' - - react-router-devtools@5.1.3: - resolution: {integrity: sha512-KQ7GL2YrMam7LkUEjaDtepst5TmShiv/2utYZq3xgMg2T//YKzF8fFPbTWDfIZe0guaWkW4s/IIgArmLbGf9Gw==} - peerDependencies: - '@types/react': '>=17' - '@types/react-dom': '>=17' - react: '>=17' - react-dom: '>=17' - react-router: '>=7.0.0' - vite: '>=5.0.0 || >=6.0.0' - react-router-hono-server@2.10.0: resolution: {integrity: sha512-IC0YKpza5BXZjXME2vuKhAflt5mWuZ7RwNDNaMytSpW2K9HhcLB3yxEkFg5rowkJdW1GYI945W34fY/qNs4Q4g==} engines: {node: '>=22.12.0'} @@ -5866,6 +5975,16 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + seroval-plugins@1.3.3: + resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.2: + resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} + engines: {node: '>=10'} + serve-static@1.16.2: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} @@ -5992,6 +6111,9 @@ packages: resolution: {integrity: sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==} engines: {node: '>= 18'} + solid-js@1.9.9: + resolution: {integrity: sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -6426,6 +6548,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -6510,6 +6636,11 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@3.0.0-beta.2: + resolution: {integrity: sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + vite-node@3.0.5: resolution: {integrity: sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -6948,6 +7079,11 @@ snapshots: dependencies: '@babel/types': 7.28.4 + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -8215,39 +8351,39 @@ snapshots: '@radix-ui/rect@1.1.1': {} - '@react-router/dev@7.9.3(@react-router/serve@7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3))(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@1.21.7)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1)': + '@react-router/dev@7.5.3(@react-router/serve@7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3))(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@1.21.7)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1)': dependencies: '@babel/core': 7.28.4 '@babel/generator': 7.28.3 '@babel/parser': 7.28.4 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.4) '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.4) + '@babel/preset-typescript': 7.26.0(@babel/core@7.28.4) '@babel/traverse': 7.28.4 '@babel/types': 7.28.4 '@npmcli/package-json': 4.0.1 - '@react-router/node': 7.9.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) - '@remix-run/node-fetch-server': 0.9.0 + '@react-router/node': 7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) arg: 5.0.2 babel-dead-code-elimination: 1.0.10 chokidar: 4.0.3 dedent: 1.7.0(babel-plugin-macros@3.1.0) es-module-lexer: 1.7.0 exit-hook: 2.2.1 - isbot: 5.1.31 + fs-extra: 10.1.0 jsesc: 3.0.2 lodash: 4.17.21 pathe: 1.1.2 picocolors: 1.1.1 - prettier: 3.6.2 + prettier: 2.8.8 react-refresh: 0.14.2 react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) semver: 7.7.2 - tinyglobby: 0.2.15 + set-cookie-parser: 2.7.1 valibot: 0.41.0(typescript@5.9.3) vite: 6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) + vite-node: 3.0.0-beta.2(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) optionalDependencies: - '@react-router/serve': 7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + '@react-router/serve': 7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - '@types/node' @@ -8315,58 +8451,17 @@ snapshots: - tsx - yaml - '@react-router/dev@7.9.3(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1)': + '@react-router/express@7.1.4(express@4.21.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3)': dependencies: - '@babel/core': 7.28.4 - '@babel/generator': 7.28.3 - '@babel/parser': 7.28.4 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.4) - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@npmcli/package-json': 4.0.1 - '@react-router/node': 7.9.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) - '@remix-run/node-fetch-server': 0.9.0 - arg: 5.0.2 - babel-dead-code-elimination: 1.0.10 - chokidar: 4.0.3 - dedent: 1.7.0(babel-plugin-macros@3.1.0) - es-module-lexer: 1.7.0 - exit-hook: 2.2.1 - isbot: 5.1.31 - jsesc: 3.0.2 - lodash: 4.17.21 - pathe: 1.1.2 - picocolors: 1.1.1 - prettier: 3.6.2 - react-refresh: 0.14.2 + '@react-router/node': 7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + express: 4.21.2 react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - semver: 7.7.2 - tinyglobby: 0.2.15 - valibot: 0.41.0(typescript@5.9.3) - vite: 6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) optionalDependencies: typescript: 5.9.3 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - bluebird - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - '@react-router/express@7.1.4(express@4.21.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3)': + '@react-router/express@7.5.3(express@4.21.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3)': dependencies: - '@react-router/node': 7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + '@react-router/node': 7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) express: 4.21.2 react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) optionalDependencies: @@ -8397,6 +8492,16 @@ snapshots: optionalDependencies: typescript: 5.9.3 + '@react-router/node@7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3)': + dependencies: + '@mjackson/node-fetch-server': 0.2.0 + react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + source-map-support: 0.5.21 + stream-slice: 0.1.2 + undici: 6.22.0 + optionalDependencies: + typescript: 5.9.3 + '@react-router/node@7.9.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3)': dependencies: '@mjackson/node-fetch-server': 0.2.0 @@ -8418,6 +8523,20 @@ snapshots: - supports-color - typescript + '@react-router/serve@7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3)': + dependencies: + '@react-router/express': 7.5.3(express@4.21.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + '@react-router/node': 7.5.3(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3) + compression: 1.8.1 + express: 4.21.2 + get-port: 5.1.1 + morgan: 1.10.1 + react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + source-map-support: 0.5.21 + transitivePeerDependencies: + - supports-color + - typescript + '@remix-run/node-fetch-server@0.9.0': {} '@remix-run/router@1.23.0': @@ -8519,6 +8638,40 @@ snapshots: ignore: 5.3.2 p-map: 4.0.0 + '@solid-primitives/event-listener@2.4.3(solid-js@1.9.9)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/keyboard@1.3.3(solid-js@1.9.9)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.9) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.9) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/resize-observer@2.1.3(solid-js@1.9.9)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.9) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.9) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.9) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/rootless@1.5.2(solid-js@1.9.9)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/static-store@0.1.2(solid-js@1.9.9)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/utils@6.3.2(solid-js@1.9.9)': + dependencies: + solid-js: 1.9.9 + '@standard-schema/spec@1.0.0': {} '@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.28.4)': @@ -8677,6 +8830,73 @@ snapshots: tailwindcss: 4.1.14 vite: 6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) + '@tanstack/devtools-client@0.0.3': + dependencies: + '@tanstack/devtools-event-client': 0.3.3 + + '@tanstack/devtools-event-bus@0.3.2': + dependencies: + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@tanstack/devtools-event-client@0.3.3': {} + + '@tanstack/devtools-ui@0.4.3(csstype@3.1.3)(solid-js@1.9.9)': + dependencies: + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + solid-js: 1.9.9 + transitivePeerDependencies: + - csstype + + '@tanstack/devtools-vite@0.3.8(vite@6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))': + dependencies: + '@babel/core': 7.28.4 + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.4 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@tanstack/devtools-client': 0.0.3 + '@tanstack/devtools-event-bus': 0.3.2 + chalk: 5.6.2 + launch-editor: 2.11.1 + vite: 6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@tanstack/devtools@0.6.21(csstype@3.1.3)(solid-js@1.9.9)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.9) + '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.9) + '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.9) + '@tanstack/devtools-client': 0.0.3 + '@tanstack/devtools-event-bus': 0.3.2 + '@tanstack/devtools-ui': 0.4.3(csstype@3.1.3)(solid-js@1.9.9) + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + solid-js: 1.9.9 + transitivePeerDependencies: + - bufferutil + - csstype + - utf-8-validate + + '@tanstack/react-devtools@0.7.7(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(csstype@3.1.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.9)': + dependencies: + '@tanstack/devtools': 0.6.21(csstype@3.1.3)(solid-js@1.9.9) + '@types/react': 19.2.0 + '@types/react-dom': 19.2.0(@types/react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + transitivePeerDependencies: + - bufferutil + - csstype + - solid-js + - utf-8-validate + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.27.1 @@ -9510,6 +9730,8 @@ snapshots: chalk@5.4.1: {} + chalk@5.6.2: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -10493,15 +10715,6 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - framer-motion@12.23.22(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - motion-dom: 12.23.21 - motion-utils: 12.23.6 - tslib: 2.8.1 - optionalDependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - fresh@0.5.2: {} fresh@2.0.0: {} @@ -10512,6 +10725,12 @@ snapshots: fs-constants@1.0.0: {} + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -10649,6 +10868,10 @@ snapshots: globrex@0.1.2: {} + goober@2.1.18(csstype@3.1.3): + dependencies: + csstype: 3.1.3 + gopd@1.2.0: {} graceful-fs@4.2.10: {} @@ -11146,6 +11369,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -11179,6 +11408,11 @@ snapshots: dependencies: package-json: 10.0.1 + launch-editor@2.11.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + lefthook-darwin-arm64@1.13.6: optional: true @@ -11830,14 +12064,8 @@ snapshots: dependencies: motion-utils: 11.18.1 - motion-dom@12.23.21: - dependencies: - motion-utils: 12.23.6 - motion-utils@11.18.1: {} - motion-utils@12.23.6: {} - mri@1.2.0: {} mrmime@2.0.1: {} @@ -12494,81 +12722,13 @@ snapshots: optionalDependencies: '@types/react': 19.2.0 - react-router-devtools@5.0.4(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)): - dependencies: - '@babel/core': 7.28.4 - '@babel/generator': 7.28.3 - '@babel/parser': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@types/react': 19.2.0 - '@types/react-dom': 19.2.0(@types/react@19.2.0) - beautify: 0.0.8 - bippy: 0.3.27(@types/react@19.2.0)(react@19.2.0) - chalk: 5.4.1 - clsx: 2.1.1 - date-fns: 4.1.0 - framer-motion: 12.23.22(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-d3-tree: 3.6.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-diff-viewer-continued: 4.0.6(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-dom: 19.2.0(react@19.2.0) - react-hotkeys-hook: 4.6.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-tooltip: 5.29.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - tailwind-merge: 3.0.1 - vite: 6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) - optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.4 - '@rollup/rollup-darwin-arm64': 4.52.4 - '@rollup/rollup-linux-x64-gnu': 4.52.4 - transitivePeerDependencies: - - '@emotion/is-prop-valid' - - supports-color - - react-router-devtools@5.1.3(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)): - dependencies: - '@babel/core': 7.28.4 - '@babel/generator': 7.28.3 - '@babel/parser': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@types/react': 19.2.0 - '@types/react-dom': 19.2.0(@types/react@19.2.0) - beautify: 0.0.8 - bippy: 0.3.27(@types/react@19.2.0)(react@19.2.0) - chalk: 5.4.1 - clsx: 2.1.1 - date-fns: 4.1.0 - framer-motion: 12.23.22(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-d3-tree: 3.6.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-diff-viewer-continued: 4.0.6(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-dom: 19.2.0(react@19.2.0) - react-hotkeys-hook: 4.6.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-tooltip: 5.29.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - tailwind-merge: 3.0.1 - vite: 6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) - optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.4 - '@rollup/rollup-darwin-arm64': 4.52.4 - '@rollup/rollup-linux-x64-gnu': 4.52.4 - transitivePeerDependencies: - - '@emotion/is-prop-valid' - - supports-color - react-router-hono-server@2.10.0(@react-router/dev@7.9.3(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1))(@types/react@19.2.0)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1)): dependencies: '@drizzle-team/brocli': 0.11.0 '@hono/node-server': 1.19.5(hono@4.6.20) '@hono/node-ws': 1.2.0(@hono/node-server@1.19.5(hono@4.6.20))(hono@4.6.20) '@hono/vite-dev-server': 0.17.0(hono@4.6.20) - '@react-router/dev': 7.9.3(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1) + '@react-router/dev': 7.9.3(@react-router/serve@7.1.4(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(typescript@5.9.3))(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(tsx@4.19.2)(typescript@5.9.3)(vite@6.3.6(@types/node@22.13.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1) '@types/react': 19.2.0 hono: 4.6.20 react-router: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -12931,6 +13091,12 @@ snapshots: dependencies: randombytes: 2.1.0 + seroval-plugins@1.3.3(seroval@1.3.2): + dependencies: + seroval: 1.3.2 + + seroval@1.3.2: {} + serve-static@1.16.2: dependencies: encodeurl: 2.0.0 @@ -13068,6 +13234,12 @@ snapshots: smol-toml@1.4.2: {} + solid-js@1.9.9: + dependencies: + csstype: 3.1.3 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -13535,6 +13707,8 @@ snapshots: universalify@0.1.2: {} + universalify@2.0.1: {} + unpipe@1.0.0: {} until-async@3.0.2: {} @@ -13610,6 +13784,27 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + vite-node@3.0.0-beta.2(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 6.3.6(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite-node@3.0.5(@types/node@22.13.1)(jiti@1.21.7)(lightningcss@1.30.2)(tsx@4.19.2)(yaml@2.8.1): dependencies: cac: 6.7.14 diff --git a/test-apps/react-router-vite/app/root.tsx b/test-apps/react-router-vite/app/root.tsx index a135db7d..9e493f50 100644 --- a/test-apps/react-router-vite/app/root.tsx +++ b/test-apps/react-router-vite/app/root.tsx @@ -1,16 +1,16 @@ import { - ActionFunctionArgs, + type ActionFunctionArgs, data, Form, Links, - LoaderFunctionArgs, + type LoaderFunctionArgs, Meta, Outlet, Scripts, ScrollRestoration, } from "react-router"; import { userSomething } from "./modules/user.server"; - +import { EmbeddedDevTools } from "../../../packages/react-router-devtools/dist/client" export const links = () => []; @@ -63,7 +63,7 @@ function App() { - + ); diff --git a/test-apps/react-router-vite/package.json b/test-apps/react-router-vite/package.json index 609c954f..e67d1b1b 100644 --- a/test-apps/react-router-vite/package.json +++ b/test-apps/react-router-vite/package.json @@ -23,7 +23,7 @@ "@types/react": "^19.1.2", "@types/react-dom": "^19.1.2", "eslint": "^9.19.0", - "react-router-devtools": "*", + "react-router-devtools": "^5.1.3", "typescript": "^5.8.3", "vite": "^6.3.3", "vite-plugin-inspect": "^10.1.0", diff --git a/test-apps/react-router-vite/vite.config.ts b/test-apps/react-router-vite/vite.config.ts index e6dd9859..4a96ecee 100644 --- a/test-apps/react-router-vite/vite.config.ts +++ b/test-apps/react-router-vite/vite.config.ts @@ -1,21 +1,13 @@ import { reactRouter } from "@react-router/dev/vite"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; -import { reactRouterDevTools, defineRdtConfig } from "react-router-devtools" +import { reactRouterDevTools, defineRdtConfig } from "../../packages/react-router-devtools/dist/index" import inspect from "vite-plugin-inspect" const config = defineRdtConfig({ client: { - enableInspector: true, - defaultOpen: false, - position: "top-right", - requireUrlFlag: false, - liveUrls: [ - { url: "https://forge42.dev", name: "Production" }, - { - url: "https://forge42.dev/staging", - name: "Staging", - }], + + }, enhancedLogs: true, pluginDir: "./plugins", @@ -33,13 +25,11 @@ const config = defineRdtConfig({ export default defineConfig({ plugins: [ inspect(), - reactRouterDevTools( config), + reactRouterDevTools( config) as any, reactRouter(), tsconfigPaths() ], - optimizeDeps: { - noDiscovery: true - }, + server: { open: true, port: 3000, From 089c8aa165db738c11f298ca343a037c7a38c90a Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Fri, 24 Oct 2025 14:40:33 +0200 Subject: [PATCH 02/32] remove tailwind for goober --- packages/react-router-devtools/package.json | 1 + .../react-router-devtools/postcss.config.js | 9 - .../src/client/components/Accordion.tsx | 55 +- .../src/client/components/Checkbox.tsx | 12 +- .../src/client/components/EditorButton.tsx | 12 +- .../src/client/components/InfoCard.tsx | 18 +- .../src/client/components/Input.tsx | 21 +- .../src/client/components/NewRouteForm.tsx | 18 +- .../src/client/components/RouteInfo.tsx | 62 +- .../src/client/components/RouteNode.tsx | 88 +- .../client/components/RouteSegmentInfo.tsx | 39 +- .../src/client/components/RouteToggle.tsx | 9 +- .../src/client/components/Select.tsx | 82 +- .../src/client/components/Stack.tsx | 11 +- .../src/client/components/Tag.tsx | 17 +- .../src/client/components/icon/Icon.tsx | 6 +- .../src/client/components/jsonRenderer.tsx | 4 +- .../components/network-tracer/NetworkBar.tsx | 9 +- .../network-tracer/NetworkPanel.tsx | 12 +- .../network-tracer/NetworkWaterfall.tsx | 123 +- .../network-tracer/RequestDetails.tsx | 81 +- .../src/client/context/rdtReducer.ts | 16 +- .../src/client/embedded-dev-tools.tsx | 4 +- .../src/client/hooks/useSetRouteBoundaries.ts | 17 +- .../src/client/layout/ContentPanel.tsx | 19 +- .../src/client/layout/MainPanel.tsx | 12 +- .../src/client/layout/Tabs.tsx | 39 +- .../src/client/react-router-dev-tools.tsx | 3 +- .../src/client/styles/tokens.ts | 298 +++ .../src/client/styles/use-styles.ts | 2113 +++++++++++++++++ .../src/client/tabs/ErrorsTab.tsx | 39 +- .../src/client/tabs/NetworkTab.tsx | 2 +- .../src/client/tabs/PageTab.tsx | 22 +- .../src/client/tabs/RoutesTab.tsx | 33 +- .../src/client/tabs/SettingsTab.tsx | 16 +- .../src/client/tabs/TimelineTab.tsx | 40 +- .../react-router-devtools/src/gradients.css | 28 - packages/react-router-devtools/src/input.css | 611 ----- .../react-router-devtools/tailwind.config.js | 38 - pnpm-lock.yaml | 3 + 40 files changed, 2913 insertions(+), 1129 deletions(-) delete mode 100644 packages/react-router-devtools/postcss.config.js create mode 100644 packages/react-router-devtools/src/client/styles/tokens.ts create mode 100644 packages/react-router-devtools/src/client/styles/use-styles.ts delete mode 100644 packages/react-router-devtools/src/gradients.css delete mode 100644 packages/react-router-devtools/src/input.css delete mode 100644 packages/react-router-devtools/tailwind.config.js diff --git a/packages/react-router-devtools/package.json b/packages/react-router-devtools/package.json index 17354257..bfc4da61 100644 --- a/packages/react-router-devtools/package.json +++ b/packages/react-router-devtools/package.json @@ -148,6 +148,7 @@ "clsx": "2.1.1", "date-fns": "^4.1.0", "framer-motion": "^11.0.8", + "goober": "^2.1.18", "react-d3-tree": "^3.6.4", "react-diff-viewer-continued": "^4.0.5", "react-hotkeys-hook": "^4.6.1", diff --git a/packages/react-router-devtools/postcss.config.js b/packages/react-router-devtools/postcss.config.js deleted file mode 100644 index 39edec5a..00000000 --- a/packages/react-router-devtools/postcss.config.js +++ /dev/null @@ -1,9 +0,0 @@ -import autoprefixer from "autoprefixer" -import tailwindcss from "tailwindcss" -import tailwindcssNesting from "tailwindcss/nesting/index.js" -import config from "./tailwind.config.js" - -/** @type {import('postcss').Config} */ -export default { - plugins: [tailwindcssNesting(), tailwindcss(config), autoprefixer()], -} diff --git a/packages/react-router-devtools/src/client/components/Accordion.tsx b/packages/react-router-devtools/src/client/components/Accordion.tsx index 01ddbe48..7c2a5d8e 100644 --- a/packages/react-router-devtools/src/client/components/Accordion.tsx +++ b/packages/react-router-devtools/src/client/components/Accordion.tsx @@ -1,54 +1,47 @@ import * as AccordionPrimitive from "@radix-ui/react-accordion" import * as React from "react" +import { cx, useStyles } from "../styles/use-styles.js" import { Icon } from "./icon/Icon.js" -import { cn } from "./util.js" const Accordion = AccordionPrimitive.Root const AccordionItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) +>(({ className, ...props }, ref) => { + const { styles } = useStyles() + return +}) AccordionItem.displayName = "AccordionItem" const AccordionTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - svg]:rotate-180", - className - )} - {...props} - > - {children} - - - -)) +>(({ className, children, ...props }, ref) => { + const { styles } = useStyles() + return ( + + + {children} + + + + ) +}) AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName const AccordionContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - -
{children}
-
-)) +>(({ className, children, ...props }, ref) => { + const { styles } = useStyles() + return ( + +
{children}
+
+ ) +}) AccordionContent.displayName = AccordionPrimitive.Content.displayName export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/packages/react-router-devtools/src/client/components/Checkbox.tsx b/packages/react-router-devtools/src/client/components/Checkbox.tsx index 3af37bc4..04a86c69 100644 --- a/packages/react-router-devtools/src/client/components/Checkbox.tsx +++ b/packages/react-router-devtools/src/client/components/Checkbox.tsx @@ -1,3 +1,5 @@ +import { useStyles } from "../styles/use-styles.js" + interface CheckboxProps extends Omit, "value"> { onChange?: (e: React.ChangeEvent) => void id: string @@ -7,11 +9,13 @@ interface CheckboxProps extends Omit } const Checkbox = ({ onChange, id, children, value, hint, ...props }: CheckboxProps) => { + const { styles } = useStyles() return ( -
-