@tanstack/query-devtools 5.91.1 → 5.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createSignal, render, lazy, setupStyleSheet, createComponent, mergeProps } from './chunk/EIDV623S.js';
1
+ import { createSignal, render, lazy, setupStyleSheet, createComponent, mergeProps } from './chunk/73LUVHE2.js';
2
2
 
3
3
  // src/TanstackQueryDevtools.tsx
4
4
  var TanstackQueryDevtools = class {
@@ -80,7 +80,7 @@ var TanstackQueryDevtools = class {
80
80
  if (this.#Component) {
81
81
  Devtools = this.#Component;
82
82
  } else {
83
- Devtools = lazy(() => import('./DevtoolsComponent/Q7LWSL4U.js'));
83
+ Devtools = lazy(() => import('./DevtoolsComponent/BAGVG3AX.js'));
84
84
  this.#Component = Devtools;
85
85
  }
86
86
  setupStyleSheet(this.#styleNonce, this.#shadowDOMTarget);
@@ -220,7 +220,7 @@ var TanstackQueryDevtoolsPanel = class {
220
220
  if (this.#Component) {
221
221
  Devtools = this.#Component;
222
222
  } else {
223
- Devtools = lazy(() => import('./DevtoolsPanelComponent/VLTTJS3N.js'));
223
+ Devtools = lazy(() => import('./DevtoolsPanelComponent/KZB72KQG.js'));
224
224
  this.#Component = Devtools;
225
225
  }
226
226
  setupStyleSheet(this.#styleNonce, this.#shadowDOMTarget);
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@tanstack/query-devtools",
3
- "version": "5.91.1",
3
+ "version": "5.93.0",
4
4
  "description": "Developer tools to interact with and visualize the TanStack Query cache",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/TanStack/query.git",
9
+ "url": "git+https://github.com/TanStack/query.git",
10
10
  "directory": "packages/query-devtools"
11
11
  },
12
12
  "homepage": "https://tanstack.com/query",
@@ -57,7 +57,7 @@
57
57
  "superjson": "^2.2.2",
58
58
  "tsup-preset-solid": "^2.2.0",
59
59
  "vite-plugin-solid": "^2.11.6",
60
- "@tanstack/query-core": "5.90.10"
60
+ "@tanstack/query-core": "5.90.20"
61
61
  },
62
62
  "scripts": {
63
63
  "clean": "premove ./build ./coverage ./dist-ts",
package/src/Devtools.tsx CHANGED
@@ -76,7 +76,6 @@ import type {
76
76
  Query,
77
77
  QueryCache,
78
78
  QueryCacheNotifyEvent,
79
- QueryState,
80
79
  } from '@tanstack/query-core'
81
80
  import type { StorageObject, StorageSetter } from '@solid-primitives/storage'
82
81
  import type { Accessor, Component, JSX, Setter } from 'solid-js'
@@ -417,6 +416,13 @@ const DraggablePanel: Component<DevtoolsPanelProps> = (props) => {
417
416
  return theme() === 'dark' ? darkStyles(css) : lightStyles(css)
418
417
  })
419
418
 
419
+ let closeBtnRef!: HTMLButtonElement
420
+
421
+ // Focus the close button when the panel opens for screen reader accessibility
422
+ onMount(() => {
423
+ closeBtnRef.focus()
424
+ })
425
+
420
426
  const [isResizing, setIsResizing] = createSignal(false)
421
427
 
422
428
  const position = createMemo(
@@ -480,7 +486,7 @@ const DraggablePanel: Component<DevtoolsPanelProps> = (props) => {
480
486
  setIsResizing(false)
481
487
  }
482
488
  document.removeEventListener('mousemove', runDrag, false)
483
- document.removeEventListener('mouseUp', unsubscribe, false)
489
+ document.removeEventListener('mouseup', unsubscribe, false)
484
490
  }
485
491
 
486
492
  document.addEventListener('mousemove', runDrag, false)
@@ -583,14 +589,73 @@ const DraggablePanel: Component<DevtoolsPanelProps> = (props) => {
583
589
  aria-label="Tanstack query devtools"
584
590
  >
585
591
  <div
592
+ role="separator"
593
+ aria-orientation={
594
+ position() === 'top' || position() === 'bottom'
595
+ ? 'horizontal'
596
+ : 'vertical'
597
+ }
598
+ aria-label="Resize devtools panel"
599
+ aria-valuemin={
600
+ position() === 'top' || position() === 'bottom'
601
+ ? convertRemToPixels(3.5)
602
+ : convertRemToPixels(12)
603
+ }
604
+ aria-valuenow={
605
+ position() === 'top' || position() === 'bottom'
606
+ ? Number(props.localStore.height || DEFAULT_HEIGHT)
607
+ : Number(props.localStore.width || DEFAULT_WIDTH)
608
+ }
609
+ tabindex="0"
586
610
  class={cx(
587
611
  styles().dragHandle,
588
612
  styles()[`dragHandle-position-${position()}`],
589
613
  'tsqd-drag-handle',
590
614
  )}
591
615
  onMouseDown={handleDragStart}
616
+ onKeyDown={(e) => {
617
+ const step = 10
618
+ const minHeight = convertRemToPixels(3.5)
619
+ const minWidth = convertRemToPixels(12)
620
+ if (position() === 'top' || position() === 'bottom') {
621
+ if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
622
+ e.preventDefault()
623
+ const currentHeight = Number(
624
+ props.localStore.height || DEFAULT_HEIGHT,
625
+ )
626
+ const delta =
627
+ position() === 'bottom'
628
+ ? e.key === 'ArrowUp'
629
+ ? step
630
+ : -step
631
+ : e.key === 'ArrowDown'
632
+ ? step
633
+ : -step
634
+ const newHeight = Math.max(minHeight, currentHeight + delta)
635
+ props.setLocalStore('height', String(newHeight))
636
+ }
637
+ } else {
638
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
639
+ e.preventDefault()
640
+ const currentWidth = Number(
641
+ props.localStore.width || DEFAULT_WIDTH,
642
+ )
643
+ const delta =
644
+ position() === 'right'
645
+ ? e.key === 'ArrowLeft'
646
+ ? step
647
+ : -step
648
+ : e.key === 'ArrowRight'
649
+ ? step
650
+ : -step
651
+ const newWidth = Math.max(minWidth, currentWidth + delta)
652
+ props.setLocalStore('width', String(newWidth))
653
+ }
654
+ }
655
+ }}
592
656
  ></div>
593
657
  <button
658
+ ref={closeBtnRef}
594
659
  aria-label="Close tanstack query devtools"
595
660
  class={cx(
596
661
  styles().closeBtn,
@@ -796,6 +861,7 @@ export const ContentView: Component<ContentViewProps> = (props) => {
796
861
  <RadioGroup.Root
797
862
  class={cx(styles().viewToggle)}
798
863
  value={selectedView()}
864
+ aria-label="Toggle between queries and mutations view"
799
865
  onChange={(value) => {
800
866
  setSelectedView(value as 'queries' | 'mutations')
801
867
  setSelectedQueryHash(null)
@@ -869,6 +935,7 @@ export const ContentView: Component<ContentViewProps> = (props) => {
869
935
  <select
870
936
  value={sort()}
871
937
  name="tsqd-queries-filter-sort"
938
+ aria-label="Sort queries by"
872
939
  onChange={(e) => {
873
940
  props.setLocalStore('sort', e.currentTarget.value)
874
941
  }}
@@ -882,6 +949,7 @@ export const ContentView: Component<ContentViewProps> = (props) => {
882
949
  <select
883
950
  value={mutationSort()}
884
951
  name="tsqd-mutations-filter-sort"
952
+ aria-label="Sort mutations by"
885
953
  onChange={(e) => {
886
954
  props.setLocalStore('mutationSort', e.currentTarget.value)
887
955
  }}
@@ -1212,10 +1280,10 @@ export const ContentView: Component<ContentViewProps> = (props) => {
1212
1280
  styles().settingsMenu,
1213
1281
  'tsqd-settings-submenu',
1214
1282
  )}
1215
- aria-label="Hide disabled queries setting"
1216
1283
  >
1217
1284
  <DropdownMenu.RadioGroup
1218
1285
  value={props.localStore.hideDisabledQueries}
1286
+ aria-label="Hide disabled queries setting"
1219
1287
  onChange={(value) =>
1220
1288
  props.setLocalStore('hideDisabledQueries', value)
1221
1289
  }
@@ -1409,7 +1477,7 @@ const QueryRow: Component<{ query: Query }> = (props) => {
1409
1477
  styles().selectedQueryRow,
1410
1478
  'tsqd-query-row',
1411
1479
  )}
1412
- aria-label={`Query key ${props.query.queryHash}`}
1480
+ aria-label={`Query key ${props.query.queryHash}${isDisabled() ? ', disabled' : ''}${isStatic() ? ', static' : ''}`}
1413
1481
  >
1414
1482
  <div
1415
1483
  class={cx(getObserverCountColorStyles(), 'tsqd-query-observer-count')}
@@ -1418,10 +1486,14 @@ const QueryRow: Component<{ query: Query }> = (props) => {
1418
1486
  </div>
1419
1487
  <code class="tsqd-query-hash">{props.query.queryHash}</code>
1420
1488
  <Show when={isDisabled()}>
1421
- <div class="tsqd-query-disabled-indicator">disabled</div>
1489
+ <div class="tsqd-query-disabled-indicator" aria-hidden="true">
1490
+ disabled
1491
+ </div>
1422
1492
  </Show>
1423
1493
  <Show when={isStatic()}>
1424
- <div class="tsqd-query-static-indicator">static</div>
1494
+ <div class="tsqd-query-static-indicator" aria-hidden="true">
1495
+ static
1496
+ </div>
1425
1497
  </Show>
1426
1498
  </button>
1427
1499
  </Show>
@@ -1710,6 +1782,7 @@ const QueryStatus: Component<QueryStatusProps> = (props) => {
1710
1782
  }}
1711
1783
  disabled={showLabel()}
1712
1784
  ref={tagRef}
1785
+ aria-label={`${props.label}: ${props.count}`}
1713
1786
  class={cx(
1714
1787
  styles().queryStatusTag,
1715
1788
  !showLabel() &&
@@ -1741,6 +1814,7 @@ const QueryStatus: Component<QueryStatusProps> = (props) => {
1741
1814
  </div>
1742
1815
  </Show>
1743
1816
  <span
1817
+ aria-hidden="true"
1744
1818
  class={cx(
1745
1819
  css`
1746
1820
  width: ${tokens.size[1.5]};
@@ -1882,13 +1956,14 @@ const QueryDetails = () => {
1882
1956
  const __previousQueryOptions = activeQueryVal.options
1883
1957
 
1884
1958
  activeQueryVal.setState({
1959
+ data: undefined,
1885
1960
  status: 'error',
1886
1961
  error,
1887
1962
  fetchMeta: {
1888
1963
  ...activeQueryVal.state.fetchMeta,
1889
1964
  __previousQueryOptions,
1890
1965
  } as any,
1891
- } as QueryState<unknown, Error>)
1966
+ })
1892
1967
  }
1893
1968
 
1894
1969
  const restoreQueryAfterLoadingOrError = () => {
@@ -1942,7 +2017,11 @@ const QueryDetails = () => {
1942
2017
  <div
1943
2018
  class={cx(styles().detailsContainer, 'tsqd-query-details-container')}
1944
2019
  >
1945
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2020
+ <div
2021
+ role="heading"
2022
+ aria-level="2"
2023
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2024
+ >
1946
2025
  Query Details
1947
2026
  </div>
1948
2027
  <div
@@ -1950,9 +2029,6 @@ const QueryDetails = () => {
1950
2029
  styles().detailsBody,
1951
2030
  'tsqd-query-details-summary-container',
1952
2031
  )}
1953
- role="status"
1954
- aria-live="polite"
1955
- aria-atomic="true"
1956
2032
  >
1957
2033
  <div class="tsqd-query-details-summary">
1958
2034
  <pre>
@@ -1960,6 +2036,8 @@ const QueryDetails = () => {
1960
2036
  </pre>
1961
2037
  <span
1962
2038
  class={cx(styles().queryDetailsStatus, getQueryStatusColors())}
2039
+ role="status"
2040
+ aria-live="polite"
1963
2041
  >
1964
2042
  {statusLabel()}
1965
2043
  </span>
@@ -1975,7 +2053,11 @@ const QueryDetails = () => {
1975
2053
  </span>
1976
2054
  </div>
1977
2055
  </div>
1978
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2056
+ <div
2057
+ role="heading"
2058
+ aria-level="2"
2059
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2060
+ >
1979
2061
  Actions
1980
2062
  </div>
1981
2063
  <div
@@ -1996,6 +2078,7 @@ const QueryDetails = () => {
1996
2078
  disabled={statusLabel() === 'fetching'}
1997
2079
  >
1998
2080
  <span
2081
+ aria-hidden="true"
1999
2082
  class={css`
2000
2083
  background-color: ${t(colors.blue[600], colors.blue[400])};
2001
2084
  `}
@@ -2020,6 +2103,7 @@ const QueryDetails = () => {
2020
2103
  disabled={queryStatus() === 'pending'}
2021
2104
  >
2022
2105
  <span
2106
+ aria-hidden="true"
2023
2107
  class={css`
2024
2108
  background-color: ${t(colors.yellow[600], colors.yellow[400])};
2025
2109
  `}
@@ -2044,6 +2128,7 @@ const QueryDetails = () => {
2044
2128
  disabled={queryStatus() === 'pending'}
2045
2129
  >
2046
2130
  <span
2131
+ aria-hidden="true"
2047
2132
  class={css`
2048
2133
  background-color: ${t(colors.gray[600], colors.gray[400])};
2049
2134
  `}
@@ -2069,6 +2154,7 @@ const QueryDetails = () => {
2069
2154
  disabled={statusLabel() === 'fetching'}
2070
2155
  >
2071
2156
  <span
2157
+ aria-hidden="true"
2072
2158
  class={css`
2073
2159
  background-color: ${t(colors.pink[500], colors.pink[400])};
2074
2160
  `}
@@ -2113,11 +2199,12 @@ const QueryDetails = () => {
2113
2199
  ...activeQueryVal.state.fetchMeta,
2114
2200
  __previousQueryOptions,
2115
2201
  } as any,
2116
- } as QueryState<unknown, Error>)
2202
+ })
2117
2203
  }
2118
2204
  }}
2119
2205
  >
2120
2206
  <span
2207
+ aria-hidden="true"
2121
2208
  class={css`
2122
2209
  background-color: ${t(colors.cyan[500], colors.cyan[400])};
2123
2210
  `}
@@ -2147,6 +2234,7 @@ const QueryDetails = () => {
2147
2234
  disabled={queryStatus() === 'pending'}
2148
2235
  >
2149
2236
  <span
2237
+ aria-hidden="true"
2150
2238
  class={css`
2151
2239
  background-color: ${t(colors.red[500], colors.red[400])};
2152
2240
  `}
@@ -2165,6 +2253,7 @@ const QueryDetails = () => {
2165
2253
  )}
2166
2254
  >
2167
2255
  <span
2256
+ aria-hidden="true"
2168
2257
  class={css`
2169
2258
  background-color: ${tokens.colors.red[400]};
2170
2259
  `}
@@ -2172,6 +2261,7 @@ const QueryDetails = () => {
2172
2261
  Trigger Error
2173
2262
  <select
2174
2263
  disabled={queryStatus() === 'pending'}
2264
+ aria-label="Select error type to trigger"
2175
2265
  onChange={(e) => {
2176
2266
  const errorType = errorTypes().find(
2177
2267
  (et) => et.name === e.currentTarget.value,
@@ -2191,7 +2281,11 @@ const QueryDetails = () => {
2191
2281
  </div>
2192
2282
  </Show>
2193
2283
  </div>
2194
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2284
+ <div
2285
+ role="heading"
2286
+ aria-level="2"
2287
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2288
+ >
2195
2289
  Data {dataMode() === 'view' ? 'Explorer' : 'Editor'}
2196
2290
  </div>
2197
2291
  <Show when={dataMode() === 'view'}>
@@ -2235,6 +2329,7 @@ const QueryDetails = () => {
2235
2329
  >
2236
2330
  <textarea
2237
2331
  name="data"
2332
+ aria-label="Edit query data as JSON"
2238
2333
  class={styles().devtoolsEditTextarea}
2239
2334
  onFocus={() => setDataEditError(false)}
2240
2335
  data-error={dataEditError()}
@@ -2271,7 +2366,11 @@ const QueryDetails = () => {
2271
2366
  </div>
2272
2367
  </form>
2273
2368
  </Show>
2274
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2369
+ <div
2370
+ role="heading"
2371
+ aria-level="2"
2372
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2373
+ >
2275
2374
  Query Explorer
2276
2375
  </div>
2277
2376
  <div
@@ -2356,7 +2455,11 @@ const MutationDetails = () => {
2356
2455
  <div
2357
2456
  class={cx(styles().detailsContainer, 'tsqd-query-details-container')}
2358
2457
  >
2359
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2458
+ <div
2459
+ role="heading"
2460
+ aria-level="2"
2461
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2462
+ >
2360
2463
  Mutation Details
2361
2464
  </div>
2362
2465
  <div
@@ -2364,9 +2467,6 @@ const MutationDetails = () => {
2364
2467
  styles().detailsBody,
2365
2468
  'tsqd-query-details-summary-container',
2366
2469
  )}
2367
- role="status"
2368
- aria-live="polite"
2369
- aria-atomic="true"
2370
2470
  >
2371
2471
  <div class="tsqd-query-details-summary">
2372
2472
  <pre>
@@ -2381,6 +2481,8 @@ const MutationDetails = () => {
2381
2481
  </pre>
2382
2482
  <span
2383
2483
  class={cx(styles().queryDetailsStatus, getQueryStatusColors())}
2484
+ role="status"
2485
+ aria-live="polite"
2384
2486
  >
2385
2487
  <Show when={color() === 'purple'}>pending</Show>
2386
2488
  <Show when={color() !== 'purple'}>{status()}</Show>
@@ -2395,7 +2497,11 @@ const MutationDetails = () => {
2395
2497
  </span>
2396
2498
  </div>
2397
2499
  </div>
2398
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2500
+ <div
2501
+ role="heading"
2502
+ aria-level="2"
2503
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2504
+ >
2399
2505
  Variables Details
2400
2506
  </div>
2401
2507
  <div
@@ -2410,7 +2516,11 @@ const MutationDetails = () => {
2410
2516
  value={activeMutation()!.state.variables}
2411
2517
  />
2412
2518
  </div>
2413
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2519
+ <div
2520
+ role="heading"
2521
+ aria-level="2"
2522
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2523
+ >
2414
2524
  Context Details
2415
2525
  </div>
2416
2526
  <div
@@ -2425,7 +2535,11 @@ const MutationDetails = () => {
2425
2535
  value={activeMutation()!.state.context}
2426
2536
  />
2427
2537
  </div>
2428
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2538
+ <div
2539
+ role="heading"
2540
+ aria-level="2"
2541
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2542
+ >
2429
2543
  Data Explorer
2430
2544
  </div>
2431
2545
  <div
@@ -2440,7 +2554,11 @@ const MutationDetails = () => {
2440
2554
  value={activeMutation()!.state.data}
2441
2555
  />
2442
2556
  </div>
2443
- <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
2557
+ <div
2558
+ role="heading"
2559
+ aria-level="2"
2560
+ class={cx(styles().detailsHeader, 'tsqd-query-details-header')}
2561
+ >
2444
2562
  Mutations Explorer
2445
2563
  </div>
2446
2564
  <div
@@ -2897,6 +3015,15 @@ const stylesFactory = (
2897
3015
  &:hover {
2898
3016
  background-color: ${colors.purple[400]}${t('', alpha[90])};
2899
3017
  }
3018
+ &:focus {
3019
+ outline: none;
3020
+ background-color: ${colors.purple[400]}${t('', alpha[90])};
3021
+ }
3022
+ &:focus-visible {
3023
+ outline: 2px solid ${colors.blue[800]};
3024
+ outline-offset: -2px;
3025
+ background-color: ${colors.purple[400]}${t('', alpha[90])};
3026
+ }
2900
3027
  z-index: 4;
2901
3028
  `,
2902
3029
  'dragHandle-position-top': css`
@@ -26,6 +26,8 @@ type PiPContextType = {
26
26
  disabled: boolean
27
27
  }
28
28
 
29
+ class PipOpenError extends Error {}
30
+
29
31
  const PiPContext = createContext<Accessor<PiPContextType> | undefined>(
30
32
  undefined,
31
33
  )
@@ -57,7 +59,7 @@ export const PiPProvider = (props: PiPProviderProps) => {
57
59
  )
58
60
 
59
61
  if (!pip) {
60
- throw new Error(
62
+ throw new PipOpenError(
61
63
  'Failed to open popup. Please allow popups for this site to view the devtools in picture-in-picture mode.',
62
64
  )
63
65
  }
@@ -134,10 +136,20 @@ export const PiPProvider = (props: PiPProviderProps) => {
134
136
  createEffect(() => {
135
137
  const pip_open = (props.localStore.pip_open ?? 'false') as 'true' | 'false'
136
138
  if (pip_open === 'true' && !props.disabled) {
137
- requestPipWindow(
138
- Number(window.innerWidth),
139
- Number(props.localStore.height || PIP_DEFAULT_HEIGHT),
140
- )
139
+ try {
140
+ requestPipWindow(
141
+ Number(window.innerWidth),
142
+ Number(props.localStore.height || PIP_DEFAULT_HEIGHT),
143
+ )
144
+ } catch (error) {
145
+ if (error instanceof PipOpenError) {
146
+ console.error(error.message)
147
+ props.setLocalStore('pip_open', 'false')
148
+ props.setLocalStore('open', 'false')
149
+ return
150
+ }
151
+ throw error
152
+ }
141
153
  }
142
154
  })
143
155