Skip to content

Commit 0e9d5b5

Browse files
feat(devtools): allow passing a theme via prop (#9887)
1 parent 66a194e commit 0e9d5b5

File tree

14 files changed

+110
-11
lines changed

14 files changed

+110
-11
lines changed

.changeset/olive-ducks-move.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@tanstack/react-query-devtools': minor
3+
'@tanstack/solid-query-devtools': minor
4+
'@tanstack/vue-query-devtools': minor
5+
'@tanstack/query-devtools': minor
6+
---
7+
8+
feat(devtools): allow passing a theme via prop

packages/query-devtools/src/DevtoolsComponent.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Devtools } from './Devtools'
44
import { getPreferredColorScheme } from './utils'
55
import { THEME_PREFERENCE } from './constants'
66
import { PiPProvider, QueryDevtoolsContext, ThemeContext } from './contexts'
7+
import type { Theme } from './contexts'
78
import type { DevtoolsComponentType } from './Devtools'
89

910
const DevtoolsComponent: DevtoolsComponentType = (props) => {
@@ -14,10 +15,9 @@ const DevtoolsComponent: DevtoolsComponentType = (props) => {
1415
const colorScheme = getPreferredColorScheme()
1516

1617
const theme = createMemo(() => {
17-
const preference = (localStore.theme_preference || THEME_PREFERENCE) as
18-
| 'system'
19-
| 'dark'
20-
| 'light'
18+
const preference = (props.theme ||
19+
localStore.theme_preference ||
20+
THEME_PREFERENCE) as Theme
2121
if (preference !== 'system') return preference
2222
return colorScheme()
2323
})

packages/query-devtools/src/DevtoolsPanelComponent.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ContentView, ParentPanel } from './Devtools'
44
import { getPreferredColorScheme } from './utils'
55
import { THEME_PREFERENCE } from './constants'
66
import { PiPProvider, QueryDevtoolsContext, ThemeContext } from './contexts'
7+
import type { Theme } from './contexts'
78
import type { DevtoolsComponentType } from './Devtools'
89

910
const DevtoolsPanelComponent: DevtoolsComponentType = (props) => {
@@ -14,10 +15,9 @@ const DevtoolsPanelComponent: DevtoolsComponentType = (props) => {
1415
const colorScheme = getPreferredColorScheme()
1516

1617
const theme = createMemo(() => {
17-
const preference = (localStore.theme_preference || THEME_PREFERENCE) as
18-
| 'system'
19-
| 'dark'
20-
| 'light'
18+
const preference = (props.theme ||
19+
localStore.theme_preference ||
20+
THEME_PREFERENCE) as Theme
2121
if (preference !== 'system') return preference
2222
return colorScheme()
2323
})

packages/query-devtools/src/TanstackQueryDevtools.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
DevtoolsErrorType,
1212
DevtoolsPosition,
1313
QueryDevtoolsProps,
14+
Theme,
1415
} from './contexts'
1516
import type { Signal } from 'solid-js'
1617

@@ -33,6 +34,7 @@ class TanstackQueryDevtools {
3334
#errorTypes: Signal<Array<DevtoolsErrorType> | undefined>
3435
#hideDisabledQueries: Signal<boolean | undefined>
3536
#Component: DevtoolsComponentType | undefined
37+
#theme: Signal<Theme | undefined>
3638
#dispose?: () => void
3739

3840
constructor(config: TanstackQueryDevtoolsConfig) {
@@ -48,6 +50,7 @@ class TanstackQueryDevtools {
4850
styleNonce,
4951
shadowDOMTarget,
5052
hideDisabledQueries,
53+
theme,
5154
} = config
5255
this.#client = createSignal(client)
5356
this.#queryFlavor = queryFlavor
@@ -60,6 +63,7 @@ class TanstackQueryDevtools {
6063
this.#initialIsOpen = createSignal(initialIsOpen)
6164
this.#errorTypes = createSignal(errorTypes)
6265
this.#hideDisabledQueries = createSignal(hideDisabledQueries)
66+
this.#theme = createSignal(theme)
6367
}
6468

6569
setButtonPosition(position: DevtoolsButtonPosition) {
@@ -82,6 +86,10 @@ class TanstackQueryDevtools {
8286
this.#client[1](client)
8387
}
8488

89+
setTheme(theme?: Theme) {
90+
this.#theme[1](theme)
91+
}
92+
8593
mount<T extends HTMLElement>(el: T) {
8694
if (this.#isMounted) {
8795
throw new Error('Devtools is already mounted')
@@ -93,6 +101,7 @@ class TanstackQueryDevtools {
93101
const [errors] = this.#errorTypes
94102
const [hideDisabledQueries] = this.#hideDisabledQueries
95103
const [queryClient] = this.#client
104+
const [theme] = this.#theme
96105
let Devtools: DevtoolsComponentType
97106

98107
if (this.#Component) {
@@ -128,6 +137,9 @@ class TanstackQueryDevtools {
128137
get hideDisabledQueries() {
129138
return hideDisabledQueries()
130139
},
140+
get theme() {
141+
return theme()
142+
},
131143
}}
132144
/>
133145
)

packages/query-devtools/src/TanstackQueryDevtoolsPanel.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
DevtoolsErrorType,
1212
DevtoolsPosition,
1313
QueryDevtoolsProps,
14+
Theme,
1415
} from './contexts'
1516
import type { Signal } from 'solid-js'
1617

@@ -35,6 +36,7 @@ class TanstackQueryDevtoolsPanel {
3536
#hideDisabledQueries: Signal<boolean | undefined>
3637
#onClose: Signal<(() => unknown) | undefined>
3738
#Component: DevtoolsComponentType | undefined
39+
#theme: Signal<Theme | undefined>
3840
#dispose?: () => void
3941

4042
constructor(config: TanstackQueryDevtoolsPanelConfig) {
@@ -51,6 +53,7 @@ class TanstackQueryDevtoolsPanel {
5153
shadowDOMTarget,
5254
onClose,
5355
hideDisabledQueries,
56+
theme,
5457
} = config
5558
this.#client = createSignal(client)
5659
this.#queryFlavor = queryFlavor
@@ -64,6 +67,7 @@ class TanstackQueryDevtoolsPanel {
6467
this.#errorTypes = createSignal(errorTypes)
6568
this.#hideDisabledQueries = createSignal(hideDisabledQueries)
6669
this.#onClose = createSignal(onClose)
70+
this.#theme = createSignal(theme)
6771
}
6872

6973
setButtonPosition(position: DevtoolsButtonPosition) {
@@ -90,6 +94,10 @@ class TanstackQueryDevtoolsPanel {
9094
this.#onClose[1](() => onClose)
9195
}
9296

97+
setTheme(theme?: Theme) {
98+
this.#theme[1](theme)
99+
}
100+
93101
mount<T extends HTMLElement>(el: T) {
94102
if (this.#isMounted) {
95103
throw new Error('Devtools is already mounted')
@@ -102,6 +110,7 @@ class TanstackQueryDevtoolsPanel {
102110
const [hideDisabledQueries] = this.#hideDisabledQueries
103111
const [queryClient] = this.#client
104112
const [onClose] = this.#onClose
113+
const [theme] = this.#theme
105114
let Devtools: DevtoolsComponentType
106115

107116
if (this.#Component) {
@@ -140,6 +149,9 @@ class TanstackQueryDevtoolsPanel {
140149
get onClose() {
141150
return onClose()
142151
},
152+
get theme() {
153+
return theme()
154+
},
143155
}}
144156
/>
145157
)

packages/query-devtools/src/contexts/QueryDevtoolsContext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type XPosition = 'left' | 'right'
55
type YPosition = 'top' | 'bottom'
66
export type DevtoolsPosition = XPosition | YPosition
77
export type DevtoolsButtonPosition = `${YPosition}-${XPosition}` | 'relative'
8+
export type Theme = 'dark' | 'light' | 'system'
89

910
export interface DevtoolsErrorType {
1011
/**
@@ -30,6 +31,7 @@ export interface QueryDevtoolsProps {
3031
shadowDOMTarget?: ShadowRoot
3132
onClose?: () => unknown
3233
hideDisabledQueries?: boolean
34+
theme?: Theme
3335
}
3436

3537
export const QueryDevtoolsContext = createContext<QueryDevtoolsProps>({

packages/query-devtools/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export type {
22
DevtoolsButtonPosition,
33
DevtoolsErrorType,
44
DevtoolsPosition,
5+
Theme,
56
} from './contexts'
67
export {
78
TanstackQueryDevtools,

packages/react-query-devtools/src/ReactQueryDevtools.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
DevtoolsButtonPosition,
77
DevtoolsErrorType,
88
DevtoolsPosition,
9+
Theme,
910
} from '@tanstack/query-devtools'
1011
import type { QueryClient } from '@tanstack/react-query'
1112

@@ -46,6 +47,11 @@ export interface DevtoolsOptions {
4647
* Set this to true to hide disabled queries from the devtools panel.
4748
*/
4849
hideDisabledQueries?: boolean
50+
/**
51+
* Set this to 'light', 'dark', or 'system' to change the theme of the devtools panel.
52+
* Defaults to 'system'.
53+
*/
54+
theme?: Theme
4955
}
5056

5157
export function ReactQueryDevtools(
@@ -61,6 +67,7 @@ export function ReactQueryDevtools(
6167
styleNonce,
6268
shadowDOMTarget,
6369
hideDisabledQueries,
70+
theme,
6471
} = props
6572
const [devtools] = React.useState(
6673
new TanstackQueryDevtools({
@@ -75,6 +82,7 @@ export function ReactQueryDevtools(
7582
styleNonce,
7683
shadowDOMTarget,
7784
hideDisabledQueries,
85+
theme,
7886
}),
7987
)
8088

@@ -102,6 +110,10 @@ export function ReactQueryDevtools(
102110
devtools.setErrorTypes(errorTypes || [])
103111
}, [errorTypes, devtools])
104112

113+
React.useEffect(() => {
114+
devtools.setTheme(theme)
115+
}, [theme, devtools])
116+
105117
React.useEffect(() => {
106118
if (ref.current) {
107119
devtools.mount(ref.current)

packages/react-query-devtools/src/ReactQueryDevtoolsPanel.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import * as React from 'react'
33
import { onlineManager, useQueryClient } from '@tanstack/react-query'
44
import { TanstackQueryDevtoolsPanel } from '@tanstack/query-devtools'
5-
import type { DevtoolsErrorType } from '@tanstack/query-devtools'
5+
import type { DevtoolsErrorType, Theme } from '@tanstack/query-devtools'
66
import type { QueryClient } from '@tanstack/react-query'
77

88
export interface DevtoolsPanelOptions {
@@ -39,14 +39,25 @@ export interface DevtoolsPanelOptions {
3939
* Set this to true to hide disabled queries from the devtools panel.
4040
*/
4141
hideDisabledQueries?: boolean
42+
/**
43+
* Set this to 'light', 'dark', or 'system' to change the theme of the devtools panel.
44+
* Defaults to 'system'.
45+
*/
46+
theme?: Theme
4247
}
4348

4449
export function ReactQueryDevtoolsPanel(
4550
props: DevtoolsPanelOptions,
4651
): React.ReactElement | null {
4752
const queryClient = useQueryClient(props.client)
4853
const ref = React.useRef<HTMLDivElement>(null)
49-
const { errorTypes, styleNonce, shadowDOMTarget, hideDisabledQueries } = props
54+
const {
55+
errorTypes,
56+
styleNonce,
57+
shadowDOMTarget,
58+
hideDisabledQueries,
59+
theme,
60+
} = props
5061
const [devtools] = React.useState(
5162
new TanstackQueryDevtoolsPanel({
5263
client: queryClient,
@@ -61,6 +72,7 @@ export function ReactQueryDevtoolsPanel(
6172
shadowDOMTarget,
6273
onClose: props.onClose,
6374
hideDisabledQueries,
75+
theme,
6476
}),
6577
)
6678

@@ -76,6 +88,10 @@ export function ReactQueryDevtoolsPanel(
7688
devtools.setErrorTypes(errorTypes || [])
7789
}, [errorTypes, devtools])
7890

91+
React.useEffect(() => {
92+
devtools.setTheme(theme)
93+
}, [theme, devtools])
94+
7995
React.useEffect(() => {
8096
if (ref.current) {
8197
devtools.mount(ref.current)

packages/solid-query-devtools/src/devtools.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
DevtoolsButtonPosition,
66
DevtoolsErrorType,
77
DevtoolsPosition,
8+
Theme,
89
} from '@tanstack/query-devtools'
910
import type { QueryClient } from '@tanstack/solid-query'
1011

@@ -45,6 +46,11 @@ interface DevtoolsOptions {
4546
* Set this to true to hide disabled queries from the devtools panel.
4647
*/
4748
hideDisabledQueries?: boolean
49+
/**
50+
* Set this to 'light', 'dark', or 'system' to change the theme of the devtools panel.
51+
* Defaults to 'system'.
52+
*/
53+
theme?: Theme
4854
}
4955

5056
export default function SolidQueryDevtools(props: DevtoolsOptions) {
@@ -63,6 +69,7 @@ export default function SolidQueryDevtools(props: DevtoolsOptions) {
6369
styleNonce: props.styleNonce,
6470
shadowDOMTarget: props.shadowDOMTarget,
6571
hideDisabledQueries: props.hideDisabledQueries,
72+
theme: props.theme,
6673
})
6774

6875
createEffect(() => {
@@ -91,6 +98,10 @@ export default function SolidQueryDevtools(props: DevtoolsOptions) {
9198
devtools.setErrorTypes(props.errorTypes || [])
9299
})
93100

101+
createEffect(() => {
102+
devtools.setTheme(props.theme || 'system')
103+
})
104+
94105
onMount(() => {
95106
devtools.mount(ref)
96107
onCleanup(() => devtools.unmount())

0 commit comments

Comments
 (0)