@tanstack/query-devtools 5.0.0-rc.1 → 5.0.0-rc.13

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/src/Devtools.tsx CHANGED
@@ -20,6 +20,7 @@ import { tokens } from './theme'
20
20
  import {
21
21
  convertRemToPixels,
22
22
  displayValue,
23
+ getPreferredColorScheme,
23
24
  getQueryStatusColor,
24
25
  getQueryStatusColorByLabel,
25
26
  getQueryStatusLabel,
@@ -32,15 +33,23 @@ import {
32
33
  ArrowRight,
33
34
  ArrowUp,
34
35
  ChevronDown,
36
+ Monitor,
37
+ Moon,
35
38
  Offline,
36
39
  Search,
37
40
  Settings,
41
+ Sun,
38
42
  TanstackLogo,
39
43
  Trash,
40
44
  Wifi,
41
45
  } from './icons'
42
46
  import Explorer from './Explorer'
43
- import { QueryDevtoolsContext, useQueryDevtoolsContext } from './Context'
47
+ import {
48
+ QueryDevtoolsContext,
49
+ ThemeContext,
50
+ useQueryDevtoolsContext,
51
+ useTheme,
52
+ } from './Context'
44
53
  import { loadFonts } from './fonts'
45
54
  import type {
46
55
  DevToolsErrorType,
@@ -69,6 +78,7 @@ const thirdBreakpoint = 700
69
78
 
70
79
  const BUTTON_POSITION: DevtoolsButtonPosition = 'bottom-right'
71
80
  const POSITION: DevtoolsPosition = 'bottom'
81
+ const THEME_PREFERENCE = 'system'
72
82
  const INITIAL_IS_OPEN = false
73
83
  const DEFAULT_HEIGHT = 500
74
84
  const DEFAULT_WIDTH = 500
@@ -81,22 +91,38 @@ const [selectedQueryHash, setSelectedQueryHash] = createSignal<string | null>(
81
91
  const [panelWidth, setPanelWidth] = createSignal(0)
82
92
 
83
93
  export const DevtoolsComponent: Component<QueryDevtoolsProps> = (props) => {
94
+ const [localStore, setLocalStore] = createLocalStorage({
95
+ prefix: 'TanstackQueryDevtools',
96
+ })
97
+
98
+ const colorScheme = getPreferredColorScheme()
99
+
100
+ const theme = createMemo(() => {
101
+ const preference = (localStore.theme_preference || THEME_PREFERENCE) as
102
+ | 'system'
103
+ | 'dark'
104
+ | 'light'
105
+ if (preference !== 'system') return preference
106
+ return colorScheme()
107
+ })
108
+
84
109
  return (
85
110
  <QueryDevtoolsContext.Provider value={props}>
86
- <Devtools />
111
+ <ThemeContext.Provider value={theme}>
112
+ <Devtools localStore={localStore} setLocalStore={setLocalStore} />
113
+ </ThemeContext.Provider>
87
114
  </QueryDevtoolsContext.Provider>
88
115
  )
89
116
  }
90
117
 
91
118
  export default DevtoolsComponent
92
119
 
93
- export const Devtools = () => {
120
+ export const Devtools: Component<DevtoolsPanelProps> = (props) => {
94
121
  loadFonts()
95
122
 
96
- const styles = getStyles()
97
-
98
- const [localStore, setLocalStore] = createLocalStorage({
99
- prefix: 'TanstackQueryDevtools',
123
+ const theme = useTheme()
124
+ const styles = createMemo(() => {
125
+ return theme() === 'dark' ? darkStyles : lightStyles
100
126
  })
101
127
 
102
128
  const buttonPosition = createMemo(() => {
@@ -104,21 +130,25 @@ export const Devtools = () => {
104
130
  })
105
131
 
106
132
  const isOpen = createMemo(() => {
107
- return localStore.open === 'true'
133
+ return props.localStore.open === 'true'
108
134
  ? true
109
- : localStore.open === 'false'
135
+ : props.localStore.open === 'false'
110
136
  ? false
111
137
  : useQueryDevtoolsContext().initialIsOpen || INITIAL_IS_OPEN
112
138
  })
113
139
 
114
140
  const position = createMemo(() => {
115
- return localStore.position || useQueryDevtoolsContext().position || POSITION
141
+ return (
142
+ props.localStore.position ||
143
+ useQueryDevtoolsContext().position ||
144
+ POSITION
145
+ )
116
146
  })
117
147
 
118
148
  createEffect(() => {
119
149
  const root = document.querySelector('.tsqd-parent-container') as HTMLElement
120
- const height = localStore.height || DEFAULT_HEIGHT
121
- const width = localStore.width || DEFAULT_WIDTH
150
+ const height = props.localStore.height || DEFAULT_HEIGHT
151
+ const width = props.localStore.width || DEFAULT_WIDTH
122
152
  const panelPosition = position()
123
153
  root.style.setProperty(
124
154
  '--tsqd-panel-height',
@@ -167,8 +197,8 @@ export const Devtools = () => {
167
197
  <TransitionGroup name="tsqd-panel-transition">
168
198
  <Show when={isOpen()}>
169
199
  <DevtoolsPanel
170
- localStore={localStore}
171
- setLocalStore={setLocalStore}
200
+ localStore={props.localStore}
201
+ setLocalStore={props.setLocalStore}
172
202
  />
173
203
  </Show>
174
204
  </TransitionGroup>
@@ -176,8 +206,8 @@ export const Devtools = () => {
176
206
  <Show when={!isOpen()}>
177
207
  <div
178
208
  class={cx(
179
- styles.devtoolsBtn,
180
- styles[`devtoolsBtn-position-${buttonPosition()}`],
209
+ styles().devtoolsBtn,
210
+ styles()[`devtoolsBtn-position-${buttonPosition()}`],
181
211
  )}
182
212
  >
183
213
  <div aria-hidden="true">
@@ -185,7 +215,7 @@ export const Devtools = () => {
185
215
  </div>
186
216
  <button
187
217
  aria-label="Open Tanstack query devtools"
188
- onClick={() => setLocalStore('open', 'true')}
218
+ onClick={() => props.setLocalStore('open', 'true')}
189
219
  >
190
220
  <TanstackLogo />
191
221
  </button>
@@ -197,7 +227,11 @@ export const Devtools = () => {
197
227
  }
198
228
 
199
229
  export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
200
- const styles = getStyles()
230
+ const theme = useTheme()
231
+ const styles = createMemo(() => {
232
+ return theme() === 'dark' ? darkStyles : lightStyles
233
+ })
234
+
201
235
  const [isResizing, setIsResizing] = createSignal(false)
202
236
 
203
237
  const sort = createMemo(() => props.localStore.sort || DEFAULT_SORT_FN_NAME)
@@ -362,6 +396,22 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
362
396
  })
363
397
  })
364
398
 
399
+ const getPanelDynamicStyles = () => {
400
+ const { colors } = tokens
401
+ const t = (light: string, dark: string) =>
402
+ theme() === 'dark' ? dark : light
403
+ if (panelWidth() < secondBreakpoint) {
404
+ return css`
405
+ flex-direction: column;
406
+ background-color: ${t(colors.gray[300], colors.gray[600])};
407
+ `
408
+ }
409
+ return css`
410
+ flex-direction: row;
411
+ background-color: ${t(colors.gray[200], colors.darkGray[900])};
412
+ `
413
+ }
414
+
365
415
  return (
366
416
  <aside
367
417
  // Some context for styles here
@@ -371,14 +421,9 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
371
421
  // min-width - When the panel is in the left or right position, the panel
372
422
  // width is set to min-content to allow the panel to shrink to the lowest possible width
373
423
  class={cx(
374
- styles.panel,
375
- styles[`panel-position-${position()}`],
376
- css`
377
- flex-direction: ${panelWidth() < secondBreakpoint ? 'column' : 'row'};
378
- background-color: ${panelWidth() < secondBreakpoint
379
- ? tokens.colors.gray[600]
380
- : tokens.colors.darkGray[900]};
381
- `,
424
+ styles().panel,
425
+ styles()[`panel-position-${position()}`],
426
+ getPanelDynamicStyles(),
382
427
  {
383
428
  [css`
384
429
  min-width: min-content;
@@ -403,8 +448,8 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
403
448
  >
404
449
  <div
405
450
  class={cx(
406
- styles.dragHandle,
407
- styles[`dragHandle-position-${position()}`],
451
+ styles().dragHandle,
452
+ styles()[`dragHandle-position-${position()}`],
408
453
  'tsqd-drag-handle',
409
454
  )}
410
455
  onMouseDown={handleDragStart}
@@ -412,8 +457,8 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
412
457
  <button
413
458
  aria-label="Close tanstack query devtools"
414
459
  class={cx(
415
- styles.closeBtn,
416
- styles[`closeBtn-position-${position()}`],
460
+ styles().closeBtn,
461
+ styles()[`closeBtn-position-${position()}`],
417
462
  'tsqd-minimize-btn',
418
463
  )}
419
464
  onClick={() => props.setLocalStore('open', 'false')}
@@ -425,7 +470,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
425
470
  // When the panels are stacked we use the height style
426
471
  // to divide the panels into two equal parts
427
472
  class={cx(
428
- styles.queriesContainer,
473
+ styles().queriesContainer,
429
474
  panelWidth() < secondBreakpoint &&
430
475
  selectedQueryHash() &&
431
476
  css`
@@ -435,17 +480,20 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
435
480
  'tsqd-queries-container',
436
481
  )}
437
482
  >
438
- <div class={cx(styles.row, 'tsqd-header')}>
483
+ <div class={cx(styles().row, 'tsqd-header')}>
439
484
  <button
440
- class={cx(styles.logo, 'tsqd-text-logo-container')}
485
+ class={cx(styles().logo, 'tsqd-text-logo-container')}
441
486
  onClick={() => props.setLocalStore('open', 'false')}
442
487
  aria-label="Close Tanstack query devtools"
443
488
  >
444
- <span class={cx(styles.tanstackLogo, 'tsqd-text-logo-tanstack')}>
489
+ <span class={cx(styles().tanstackLogo, 'tsqd-text-logo-tanstack')}>
445
490
  TANSTACK
446
491
  </span>
447
492
  <span
448
- class={cx(styles.queryFlavorLogo, 'tsqd-text-logo-query-flavor')}
493
+ class={cx(
494
+ styles().queryFlavorLogo,
495
+ 'tsqd-text-logo-query-flavor',
496
+ )}
449
497
  >
450
498
  {useQueryDevtoolsContext().queryFlavor} v
451
499
  {useQueryDevtoolsContext().version}
@@ -455,17 +503,17 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
455
503
  </div>
456
504
  <div
457
505
  class={cx(
458
- styles.row,
506
+ styles().row,
459
507
  css`
460
508
  gap: ${tokens.size[2.5]};
461
509
  `,
462
510
  'tsqd-filters-actions-container',
463
511
  )}
464
512
  >
465
- <div class={cx(styles.filtersContainer, 'tsqd-filters-container')}>
513
+ <div class={cx(styles().filtersContainer, 'tsqd-filters-container')}>
466
514
  <div
467
515
  class={cx(
468
- styles.filterInput,
516
+ styles().filterInput,
469
517
  'tsqd-query-filter-textfield-container',
470
518
  )}
471
519
  >
@@ -483,7 +531,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
483
531
  </div>
484
532
  <div
485
533
  class={cx(
486
- styles.filterSelect,
534
+ styles().filterSelect,
487
535
  'tsqd-query-filter-sort-container',
488
536
  )}
489
537
  >
@@ -520,13 +568,13 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
520
568
  </button>
521
569
  </div>
522
570
 
523
- <div class={cx(styles.actionsContainer, 'tsqd-actions-container')}>
571
+ <div class={cx(styles().actionsContainer, 'tsqd-actions-container')}>
524
572
  <button
525
573
  onClick={() => {
526
574
  cache().clear()
527
575
  }}
528
576
  class={cx(
529
- styles.actionsBtn,
577
+ styles().actionsBtn,
530
578
  'tsqd-actions-btn',
531
579
  'tsqd-action-clear-cache',
532
580
  )}
@@ -546,7 +594,8 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
546
594
  }
547
595
  }}
548
596
  class={cx(
549
- styles.actionsBtn,
597
+ styles().actionsBtn,
598
+ offline() && styles().actionsBtnOffline,
550
599
  'tsqd-actions-btn',
551
600
  'tsqd-action-mock-offline-behavior',
552
601
  )}
@@ -568,7 +617,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
568
617
  <DropdownMenu.Root gutter={4}>
569
618
  <DropdownMenu.Trigger
570
619
  class={cx(
571
- styles.actionsBtn,
620
+ styles().actionsBtn,
572
621
  'tsqd-actions-btn',
573
622
  'tsqd-action-settings',
574
623
  )}
@@ -577,11 +626,11 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
577
626
  </DropdownMenu.Trigger>
578
627
  <DropdownMenu.Portal>
579
628
  <DropdownMenu.Content
580
- class={cx(styles.settingsMenu, 'tsqd-settings-menu')}
629
+ class={cx(styles().settingsMenu, 'tsqd-settings-menu')}
581
630
  >
582
631
  <div
583
632
  class={cx(
584
- styles.settingsMenuHeader,
633
+ styles().settingsMenuHeader,
585
634
  'tsqd-settings-menu-header',
586
635
  )}
587
636
  >
@@ -590,7 +639,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
590
639
  <DropdownMenu.Sub overlap gutter={8} shift={-4}>
591
640
  <DropdownMenu.SubTrigger
592
641
  class={cx(
593
- styles.settingsSubTrigger,
642
+ styles().settingsSubTrigger,
594
643
  'tsqd-settings-menu-sub-trigger',
595
644
  'tsqd-settings-menu-sub-trigger-position',
596
645
  )}
@@ -600,7 +649,10 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
600
649
  </DropdownMenu.SubTrigger>
601
650
  <DropdownMenu.Portal>
602
651
  <DropdownMenu.SubContent
603
- class={cx(styles.settingsMenu, 'tsqd-settings-submenu')}
652
+ class={cx(
653
+ styles().settingsMenu,
654
+ 'tsqd-settings-submenu',
655
+ )}
604
656
  >
605
657
  <DropdownMenu.Item
606
658
  onSelect={() => {
@@ -608,7 +660,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
608
660
  }}
609
661
  as="button"
610
662
  class={cx(
611
- styles.settingsSubButton,
663
+ styles().settingsSubButton,
612
664
  'tsqd-settings-menu-position-btn',
613
665
  'tsqd-settings-menu-position-btn-top',
614
666
  )}
@@ -622,7 +674,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
622
674
  }}
623
675
  as="button"
624
676
  class={cx(
625
- styles.settingsSubButton,
677
+ styles().settingsSubButton,
626
678
  'tsqd-settings-menu-position-btn',
627
679
  'tsqd-settings-menu-position-btn-bottom',
628
680
  )}
@@ -636,7 +688,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
636
688
  }}
637
689
  as="button"
638
690
  class={cx(
639
- styles.settingsSubButton,
691
+ styles().settingsSubButton,
640
692
  'tsqd-settings-menu-position-btn',
641
693
  'tsqd-settings-menu-position-btn-left',
642
694
  )}
@@ -650,7 +702,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
650
702
  }}
651
703
  as="button"
652
704
  class={cx(
653
- styles.settingsSubButton,
705
+ styles().settingsSubButton,
654
706
  'tsqd-settings-menu-position-btn',
655
707
  'tsqd-settings-menu-position-btn-right',
656
708
  )}
@@ -661,6 +713,75 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
661
713
  </DropdownMenu.SubContent>
662
714
  </DropdownMenu.Portal>
663
715
  </DropdownMenu.Sub>
716
+ <DropdownMenu.Sub overlap gutter={8} shift={-4}>
717
+ <DropdownMenu.SubTrigger
718
+ class={cx(
719
+ styles().settingsSubTrigger,
720
+ 'tsqd-settings-menu-sub-trigger',
721
+ 'tsqd-settings-menu-sub-trigger-position',
722
+ )}
723
+ >
724
+ <span>Theme</span>
725
+ <ChevronDown />
726
+ </DropdownMenu.SubTrigger>
727
+ <DropdownMenu.Portal>
728
+ <DropdownMenu.SubContent
729
+ class={cx(
730
+ styles().settingsMenu,
731
+ 'tsqd-settings-submenu',
732
+ )}
733
+ >
734
+ <DropdownMenu.Item
735
+ onSelect={() => {
736
+ props.setLocalStore('theme_preference', 'light')
737
+ }}
738
+ as="button"
739
+ class={cx(
740
+ styles().settingsSubButton,
741
+ props.localStore.theme_preference === 'light' &&
742
+ styles().themeSelectedButton,
743
+ 'tsqd-settings-menu-position-btn',
744
+ 'tsqd-settings-menu-position-btn-top',
745
+ )}
746
+ >
747
+ <span>Light</span>
748
+ <Sun />
749
+ </DropdownMenu.Item>
750
+ <DropdownMenu.Item
751
+ onSelect={() => {
752
+ props.setLocalStore('theme_preference', 'dark')
753
+ }}
754
+ as="button"
755
+ class={cx(
756
+ styles().settingsSubButton,
757
+ props.localStore.theme_preference === 'dark' &&
758
+ styles().themeSelectedButton,
759
+ 'tsqd-settings-menu-position-btn',
760
+ 'tsqd-settings-menu-position-btn-bottom',
761
+ )}
762
+ >
763
+ <span>Dark</span>
764
+ <Moon />
765
+ </DropdownMenu.Item>
766
+ <DropdownMenu.Item
767
+ onSelect={() => {
768
+ props.setLocalStore('theme_preference', 'system')
769
+ }}
770
+ as="button"
771
+ class={cx(
772
+ styles().settingsSubButton,
773
+ props.localStore.theme_preference === 'system' &&
774
+ styles().themeSelectedButton,
775
+ 'tsqd-settings-menu-position-btn',
776
+ 'tsqd-settings-menu-position-btn-left',
777
+ )}
778
+ >
779
+ <span>System</span>
780
+ <Monitor />
781
+ </DropdownMenu.Item>
782
+ </DropdownMenu.SubContent>
783
+ </DropdownMenu.Portal>
784
+ </DropdownMenu.Sub>
664
785
  </DropdownMenu.Content>
665
786
  </DropdownMenu.Portal>
666
787
  </DropdownMenu.Root>
@@ -668,7 +789,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
668
789
  </div>
669
790
  <div
670
791
  class={cx(
671
- styles.overflowQueryContainer,
792
+ styles().overflowQueryContainer,
672
793
  'tsqd-queries-overflow-container',
673
794
  )}
674
795
  >
@@ -687,7 +808,13 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
687
808
  }
688
809
 
689
810
  export const QueryRow: Component<{ query: Query }> = (props) => {
690
- const styles = getStyles()
811
+ const theme = useTheme()
812
+ const styles = createMemo(() => {
813
+ return theme() === 'dark' ? darkStyles : lightStyles
814
+ })
815
+
816
+ const { colors, alpha } = tokens
817
+ const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
691
818
 
692
819
  const queryState = createSubscribeToQueryCacheBatcher(
693
820
  (queryCache) =>
@@ -731,6 +858,23 @@ export const QueryRow: Component<{ query: Query }> = (props) => {
731
858
  }),
732
859
  )
733
860
 
861
+ const getObserverCountColorStyles = () => {
862
+ if (color() === 'gray') {
863
+ return css`
864
+ background-color: ${t(colors[color()][200], colors[color()][700])};
865
+ color: ${t(colors[color()][700], colors[color()][300])};
866
+ `
867
+ }
868
+
869
+ return css`
870
+ background-color: ${t(
871
+ colors[color()][200] + alpha[80],
872
+ colors[color()][900],
873
+ )};
874
+ color: ${t(colors[color()][800], colors[color()][300])};
875
+ `
876
+ }
877
+
734
878
  return (
735
879
  <Show when={queryState()}>
736
880
  <button
@@ -742,26 +886,15 @@ export const QueryRow: Component<{ query: Query }> = (props) => {
742
886
  )
743
887
  }
744
888
  class={cx(
745
- styles.queryRow,
889
+ styles().queryRow,
746
890
  selectedQueryHash() === props.query.queryHash &&
747
- styles.selectedQueryRow,
891
+ styles().selectedQueryRow,
748
892
  'tsqd-query-row',
749
893
  )}
750
894
  aria-label={`Query key ${props.query.queryHash}`}
751
895
  >
752
896
  <div
753
- class={cx(
754
- color() === 'gray'
755
- ? css`
756
- background-color: ${tokens.colors[color()][700]};
757
- color: ${tokens.colors[color()][300]};
758
- `
759
- : css`
760
- background-color: ${tokens.colors[color()][900]};
761
- color: ${tokens.colors[color()][300]};
762
- `,
763
- 'tsqd-query-observer-count',
764
- )}
897
+ class={cx(getObserverCountColorStyles(), 'tsqd-query-observer-count')}
765
898
  >
766
899
  {observers()}
767
900
  </div>
@@ -810,10 +943,15 @@ export const QueryStatusCount: Component = () => {
810
943
  .filter((q) => getQueryStatusLabel(q) === 'inactive').length,
811
944
  )
812
945
 
813
- const styles = getStyles()
946
+ const theme = useTheme()
947
+ const styles = createMemo(() => {
948
+ return theme() === 'dark' ? darkStyles : lightStyles
949
+ })
814
950
 
815
951
  return (
816
- <div class={cx(styles.queryStatusContainer, 'tsqd-query-status-container')}>
952
+ <div
953
+ class={cx(styles().queryStatusContainer, 'tsqd-query-status-container')}
954
+ >
817
955
  <QueryStatus label="Fresh" color="green" count={fresh()} />
818
956
  <QueryStatus label="Fetching" color="blue" count={fetching()} />
819
957
  <QueryStatus label="Paused" color="purple" count={paused()} />
@@ -824,7 +962,13 @@ export const QueryStatusCount: Component = () => {
824
962
  }
825
963
 
826
964
  export const QueryStatus: Component<QueryStatusProps> = (props) => {
827
- const styles = getStyles()
965
+ const theme = useTheme()
966
+ const styles = createMemo(() => {
967
+ return theme() === 'dark' ? darkStyles : lightStyles
968
+ })
969
+
970
+ const { colors, alpha } = tokens
971
+ const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
828
972
 
829
973
  let tagRef!: HTMLButtonElement
830
974
 
@@ -856,12 +1000,12 @@ export const QueryStatus: Component<QueryStatusProps> = (props) => {
856
1000
  disabled={showLabel()}
857
1001
  ref={tagRef}
858
1002
  class={cx(
859
- styles.queryStatusTag,
1003
+ styles().queryStatusTag,
860
1004
  !showLabel() &&
861
1005
  css`
862
1006
  cursor: pointer;
863
1007
  &:hover {
864
- background: ${tokens.colors.darkGray[400]}${tokens.alpha[80]};
1008
+ background: ${t(colors.gray[200], colors.darkGray[400])}${alpha[80]};
865
1009
  }
866
1010
  `,
867
1011
  'tsqd-query-status-tag',
@@ -877,7 +1021,7 @@ export const QueryStatus: Component<QueryStatusProps> = (props) => {
877
1021
  <div
878
1022
  role="tooltip"
879
1023
  id="tsqd-status-tooltip"
880
- class={cx(styles.statusTooltip, 'tsqd-query-status-tooltip')}
1024
+ class={cx(styles().statusTooltip, 'tsqd-query-status-tooltip')}
881
1025
  >
882
1026
  {props.label}
883
1027
  </div>
@@ -895,22 +1039,26 @@ export const QueryStatus: Component<QueryStatusProps> = (props) => {
895
1039
  />
896
1040
  <Show when={showLabel()}>
897
1041
  <span
898
- class={cx(styles.queryStatusTagLabel, 'tsqd-query-status-tag-label')}
1042
+ class={cx(
1043
+ styles().queryStatusTagLabel,
1044
+ 'tsqd-query-status-tag-label',
1045
+ )}
899
1046
  >
900
1047
  {props.label}
901
1048
  </span>
902
1049
  </Show>
903
1050
  <span
904
1051
  class={cx(
905
- styles.queryStatusCount,
906
- props.count > 0 && props.color !== 'gray'
907
- ? css`
908
- background-color: ${tokens.colors[props.color][900]};
909
- color: ${tokens.colors[props.color][300]};
910
- `
911
- : css`
912
- color: ${tokens.colors['gray'][400]};
913
- `,
1052
+ styles().queryStatusCount,
1053
+ props.count > 0 &&
1054
+ props.color !== 'gray' &&
1055
+ css`
1056
+ background-color: ${t(
1057
+ colors[props.color][100],
1058
+ colors[props.color][900],
1059
+ )};
1060
+ color: ${t(colors[props.color][700], colors[props.color][300])};
1061
+ `,
914
1062
  'tsqd-query-status-tag-count',
915
1063
  )}
916
1064
  >
@@ -921,7 +1069,14 @@ export const QueryStatus: Component<QueryStatusProps> = (props) => {
921
1069
  }
922
1070
 
923
1071
  const QueryDetails = () => {
924
- const styles = getStyles()
1072
+ const theme = useTheme()
1073
+ const styles = createMemo(() => {
1074
+ return theme() === 'dark' ? darkStyles : lightStyles
1075
+ })
1076
+
1077
+ const { colors } = tokens
1078
+ const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
1079
+
925
1080
  const queryClient = useQueryDevtoolsContext().client
926
1081
 
927
1082
  const [restoringLoading, setRestoringLoading] = createSignal(false)
@@ -1027,34 +1182,41 @@ const QueryDetails = () => {
1027
1182
  }
1028
1183
  })
1029
1184
 
1185
+ const getQueryStatusColors = () => {
1186
+ if (color() === 'gray') {
1187
+ return css`
1188
+ background-color: ${t(colors[color()][200], colors[color()][700])};
1189
+ color: ${t(colors[color()][700], colors[color()][300])};
1190
+ border-color: ${t(colors[color()][400], colors[color()][600])};
1191
+ `
1192
+ }
1193
+ return css`
1194
+ background-color: ${t(colors[color()][100], colors[color()][900])};
1195
+ color: ${t(colors[color()][700], colors[color()][300])};
1196
+ border-color: ${t(colors[color()][400], colors[color()][600])};
1197
+ `
1198
+ }
1199
+
1030
1200
  return (
1031
1201
  <Show when={activeQuery() && activeQueryState()}>
1032
- <div class={cx(styles.detailsContainer, 'tsqd-query-details-container')}>
1033
- <div class={cx(styles.detailsHeader, 'tsqd-query-details-header')}>
1202
+ <div
1203
+ class={cx(styles().detailsContainer, 'tsqd-query-details-container')}
1204
+ >
1205
+ <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
1034
1206
  Query Details
1035
1207
  </div>
1036
1208
  <div
1037
- class={cx(styles.detailsBody, 'tsqd-query-details-summary-container')}
1209
+ class={cx(
1210
+ styles().detailsBody,
1211
+ 'tsqd-query-details-summary-container',
1212
+ )}
1038
1213
  >
1039
1214
  <div class="tsqd-query-details-summary">
1040
1215
  <pre>
1041
1216
  <code>{displayValue(activeQuery()!.queryKey, true)}</code>
1042
1217
  </pre>
1043
1218
  <span
1044
- class={cx(
1045
- styles.queryDetailsStatus,
1046
- color() === 'gray'
1047
- ? css`
1048
- background-color: ${tokens.colors[color()][700]};
1049
- color: ${tokens.colors[color()][300]};
1050
- border-color: ${tokens.colors[color()][600]};
1051
- `
1052
- : css`
1053
- background-color: ${tokens.colors[color()][900]};
1054
- color: ${tokens.colors[color()][300]};
1055
- border-color: ${tokens.colors[color()][600]};
1056
- `,
1057
- )}
1219
+ class={cx(styles().queryDetailsStatus, getQueryStatusColors())}
1058
1220
  >
1059
1221
  {statusLabel()}
1060
1222
  </span>
@@ -1070,16 +1232,19 @@ const QueryDetails = () => {
1070
1232
  </span>
1071
1233
  </div>
1072
1234
  </div>
1073
- <div class={cx(styles.detailsHeader, 'tsqd-query-details-header')}>
1235
+ <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
1074
1236
  Actions
1075
1237
  </div>
1076
1238
  <div
1077
- class={cx(styles.actionsBody, 'tsqd-query-details-actions-container')}
1239
+ class={cx(
1240
+ styles().actionsBody,
1241
+ 'tsqd-query-details-actions-container',
1242
+ )}
1078
1243
  >
1079
1244
  <button
1080
1245
  class={cx(
1081
1246
  css`
1082
- color: ${tokens.colors.blue[400]};
1247
+ color: ${t(colors.blue[600], colors.blue[400])};
1083
1248
  `,
1084
1249
  'tsqd-query-details-actions-btn',
1085
1250
  'tsqd-query-details-action-refetch',
@@ -1089,7 +1254,7 @@ const QueryDetails = () => {
1089
1254
  >
1090
1255
  <span
1091
1256
  class={css`
1092
- background-color: ${tokens.colors.blue[400]};
1257
+ background-color: ${t(colors.blue[600], colors.blue[400])};
1093
1258
  `}
1094
1259
  ></span>
1095
1260
  Refetch
@@ -1097,7 +1262,7 @@ const QueryDetails = () => {
1097
1262
  <button
1098
1263
  class={cx(
1099
1264
  css`
1100
- color: ${tokens.colors.yellow[400]};
1265
+ color: ${t(colors.yellow[600], colors.yellow[400])};
1101
1266
  `,
1102
1267
  'tsqd-query-details-actions-btn',
1103
1268
  'tsqd-query-details-action-invalidate',
@@ -1107,7 +1272,7 @@ const QueryDetails = () => {
1107
1272
  >
1108
1273
  <span
1109
1274
  class={css`
1110
- background-color: ${tokens.colors.yellow[400]};
1275
+ background-color: ${t(colors.yellow[600], colors.yellow[400])};
1111
1276
  `}
1112
1277
  ></span>
1113
1278
  Invalidate
@@ -1115,7 +1280,7 @@ const QueryDetails = () => {
1115
1280
  <button
1116
1281
  class={cx(
1117
1282
  css`
1118
- color: ${tokens.colors.gray[300]};
1283
+ color: ${t(colors.gray[600], colors.gray[300])};
1119
1284
  `,
1120
1285
  'tsqd-query-details-actions-btn',
1121
1286
  'tsqd-query-details-action-reset',
@@ -1125,7 +1290,7 @@ const QueryDetails = () => {
1125
1290
  >
1126
1291
  <span
1127
1292
  class={css`
1128
- background-color: ${tokens.colors.gray[400]};
1293
+ background-color: ${t(colors.gray[600], colors.gray[400])};
1129
1294
  `}
1130
1295
  ></span>
1131
1296
  Reset
@@ -1133,7 +1298,7 @@ const QueryDetails = () => {
1133
1298
  <button
1134
1299
  class={cx(
1135
1300
  css`
1136
- color: ${tokens.colors.pink[400]};
1301
+ color: ${t(colors.pink[500], colors.pink[400])};
1137
1302
  `,
1138
1303
  'tsqd-query-details-actions-btn',
1139
1304
  'tsqd-query-details-action-remove',
@@ -1146,7 +1311,7 @@ const QueryDetails = () => {
1146
1311
  >
1147
1312
  <span
1148
1313
  class={css`
1149
- background-color: ${tokens.colors.pink[400]};
1314
+ background-color: ${t(colors.pink[500], colors.pink[400])};
1150
1315
  `}
1151
1316
  ></span>
1152
1317
  Remove
@@ -1154,7 +1319,7 @@ const QueryDetails = () => {
1154
1319
  <button
1155
1320
  class={cx(
1156
1321
  css`
1157
- color: ${tokens.colors.cyan[400]};
1322
+ color: ${t(colors.cyan[500], colors.cyan[400])};
1158
1323
  `,
1159
1324
  'tsqd-query-details-actions-btn',
1160
1325
  'tsqd-query-details-action-loading',
@@ -1192,7 +1357,7 @@ const QueryDetails = () => {
1192
1357
  >
1193
1358
  <span
1194
1359
  class={css`
1195
- background-color: ${tokens.colors.cyan[400]};
1360
+ background-color: ${t(colors.cyan[500], colors.cyan[400])};
1196
1361
  `}
1197
1362
  ></span>
1198
1363
  {queryStatus() === 'pending' ? 'Restore' : 'Trigger'} Loading
@@ -1201,7 +1366,7 @@ const QueryDetails = () => {
1201
1366
  <button
1202
1367
  class={cx(
1203
1368
  css`
1204
- color: ${tokens.colors.red[400]};
1369
+ color: ${t(colors.red[500], colors.red[400])};
1205
1370
  `,
1206
1371
  'tsqd-query-details-actions-btn',
1207
1372
  'tsqd-query-details-action-error',
@@ -1217,7 +1382,7 @@ const QueryDetails = () => {
1217
1382
  >
1218
1383
  <span
1219
1384
  class={css`
1220
- background-color: ${tokens.colors.red[400]};
1385
+ background-color: ${t(colors.red[500], colors.red[400])};
1221
1386
  `}
1222
1387
  ></span>
1223
1388
  {queryStatus() === 'error' ? 'Restore' : 'Trigger'} Error
@@ -1228,7 +1393,7 @@ const QueryDetails = () => {
1228
1393
  >
1229
1394
  <div
1230
1395
  class={cx(
1231
- styles.actionsSelect,
1396
+ styles().actionsSelect,
1232
1397
  'tsqd-query-details-actions-btn',
1233
1398
  'tsqd-query-details-action-error-multiple',
1234
1399
  )}
@@ -1243,7 +1408,7 @@ const QueryDetails = () => {
1243
1408
  disabled={queryStatus() === 'pending'}
1244
1409
  onChange={(e) => {
1245
1410
  const errorType = errorTypes().find(
1246
- (t) => t.name === e.currentTarget.value,
1411
+ (et) => et.name === e.currentTarget.value,
1247
1412
  )
1248
1413
 
1249
1414
  triggerError(errorType)
@@ -1260,7 +1425,7 @@ const QueryDetails = () => {
1260
1425
  </div>
1261
1426
  </Show>
1262
1427
  </div>
1263
- <div class={cx(styles.detailsHeader, 'tsqd-query-details-header')}>
1428
+ <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
1264
1429
  Data Explorer
1265
1430
  </div>
1266
1431
  <div
@@ -1273,10 +1438,11 @@ const QueryDetails = () => {
1273
1438
  label="Data"
1274
1439
  defaultExpanded={['Data']}
1275
1440
  value={activeQueryStateData()}
1276
- copyable={true}
1441
+ editable={true}
1442
+ activeQuery={activeQuery()}
1277
1443
  />
1278
1444
  </div>
1279
- <div class={cx(styles.detailsHeader, 'tsqd-query-details-header')}>
1445
+ <div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
1280
1446
  Query Explorer
1281
1447
  </div>
1282
1448
  <div
@@ -1349,9 +1515,11 @@ const createSubscribeToQueryCacheBatcher = <T,>(
1349
1515
  return value
1350
1516
  }
1351
1517
 
1352
- const getStyles = () => {
1518
+ const stylesFactory = (theme: 'light' | 'dark') => {
1353
1519
  const { colors, font, size, alpha, shadow, border } = tokens
1354
1520
 
1521
+ const t = (light: string, dark: string) => (theme === 'light' ? light : dark)
1522
+
1355
1523
  return {
1356
1524
  devtoolsBtn: css`
1357
1525
  z-index: 100000;
@@ -1413,8 +1581,6 @@ const getStyles = () => {
1413
1581
  display: flex;
1414
1582
  gap: ${tokens.size[0.5]};
1415
1583
  & * {
1416
- font-family: 'Inter', sans-serif;
1417
- color: ${colors.gray[300]};
1418
1584
  box-sizing: border-box;
1419
1585
  text-transform: none;
1420
1586
  }
@@ -1441,7 +1607,7 @@ const getStyles = () => {
1441
1607
  left: 0;
1442
1608
  max-height: 90%;
1443
1609
  min-height: 3.5rem;
1444
- border-bottom: ${colors.darkGray[300]} 1px solid;
1610
+ border-bottom: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1445
1611
  `,
1446
1612
  'panel-position-bottom': css`
1447
1613
  bottom: 0;
@@ -1449,20 +1615,20 @@ const getStyles = () => {
1449
1615
  left: 0;
1450
1616
  max-height: 90%;
1451
1617
  min-height: 3.5rem;
1452
- border-top: ${colors.darkGray[300]} 1px solid;
1618
+ border-top: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1453
1619
  `,
1454
1620
  'panel-position-right': css`
1455
1621
  bottom: 0;
1456
1622
  right: 0;
1457
1623
  top: 0;
1458
- border-left: ${colors.darkGray[300]} 1px solid;
1624
+ border-left: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1459
1625
  max-width: 90%;
1460
1626
  `,
1461
1627
  'panel-position-left': css`
1462
1628
  bottom: 0;
1463
1629
  left: 0;
1464
1630
  top: 0;
1465
- border-right: ${colors.darkGray[300]} 1px solid;
1631
+ border-right: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1466
1632
  max-width: 90%;
1467
1633
  `,
1468
1634
  closeBtn: css`
@@ -1473,13 +1639,15 @@ const getStyles = () => {
1473
1639
  align-items: center;
1474
1640
  justify-content: center;
1475
1641
  outline: none;
1642
+ background-color: ${t(colors.gray[50], colors.darkGray[700])};
1476
1643
  &:hover {
1477
- background-color: ${colors.darkGray[500]};
1644
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
1478
1645
  }
1479
1646
  &:focus-visible {
1480
1647
  outline: 2px solid ${colors.blue[600]};
1481
1648
  }
1482
1649
  & svg {
1650
+ color: ${t(colors.gray[600], colors.gray[400])};
1483
1651
  width: ${size[2]};
1484
1652
  height: ${size[2]};
1485
1653
  }
@@ -1488,11 +1656,10 @@ const getStyles = () => {
1488
1656
  bottom: 0;
1489
1657
  right: ${size[2]};
1490
1658
  transform: translate(0, 100%);
1491
- background-color: ${colors.darkGray[700]};
1492
- border-right: ${colors.darkGray[300]} 1px solid;
1493
- border-left: ${colors.darkGray[300]} 1px solid;
1659
+ border-right: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1660
+ border-left: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1494
1661
  border-top: none;
1495
- border-bottom: ${colors.darkGray[300]} 1px solid;
1662
+ border-bottom: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1496
1663
  border-radius: 0px 0px ${border.radius.sm} ${border.radius.sm};
1497
1664
  padding: ${size[0.5]} ${size[1.5]} ${size[1]} ${size[1.5]};
1498
1665
 
@@ -1513,10 +1680,9 @@ const getStyles = () => {
1513
1680
  top: 0;
1514
1681
  right: ${size[2]};
1515
1682
  transform: translate(0, -100%);
1516
- background-color: ${colors.darkGray[700]};
1517
- border-right: ${colors.darkGray[300]} 1px solid;
1518
- border-left: ${colors.darkGray[300]} 1px solid;
1519
- border-top: ${colors.darkGray[300]} 1px solid;
1683
+ border-right: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1684
+ border-left: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1685
+ border-top: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1520
1686
  border-bottom: none;
1521
1687
  border-radius: ${border.radius.sm} ${border.radius.sm} 0px 0px;
1522
1688
  padding: ${size[1]} ${size[1.5]} ${size[0.5]} ${size[1.5]};
@@ -1534,11 +1700,10 @@ const getStyles = () => {
1534
1700
  bottom: ${size[2]};
1535
1701
  left: 0;
1536
1702
  transform: translate(-100%, 0);
1537
- background-color: ${colors.darkGray[700]};
1538
1703
  border-right: none;
1539
- border-left: ${colors.darkGray[300]} 1px solid;
1540
- border-top: ${colors.darkGray[300]} 1px solid;
1541
- border-bottom: ${colors.darkGray[300]} 1px solid;
1704
+ border-left: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1705
+ border-top: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1706
+ border-bottom: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1542
1707
  border-radius: ${border.radius.sm} 0px 0px ${border.radius.sm};
1543
1708
  padding: ${size[1.5]} ${size[0.5]} ${size[1.5]} ${size[1]};
1544
1709
 
@@ -1558,11 +1723,10 @@ const getStyles = () => {
1558
1723
  bottom: ${size[2]};
1559
1724
  right: 0;
1560
1725
  transform: translate(100%, 0);
1561
- background-color: ${colors.darkGray[700]};
1562
1726
  border-left: none;
1563
- border-right: ${colors.darkGray[300]} 1px solid;
1564
- border-top: ${colors.darkGray[300]} 1px solid;
1565
- border-bottom: ${colors.darkGray[300]} 1px solid;
1727
+ border-right: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1728
+ border-top: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1729
+ border-bottom: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
1566
1730
  border-radius: 0px ${border.radius.sm} ${border.radius.sm} 0px;
1567
1731
  padding: ${size[1.5]} ${size[1]} ${size[1.5]} ${size[0.5]};
1568
1732
 
@@ -1580,15 +1744,18 @@ const getStyles = () => {
1580
1744
  `,
1581
1745
  queriesContainer: css`
1582
1746
  flex: 1 1 700px;
1583
- background-color: ${colors.darkGray[700]};
1747
+ background-color: ${t(colors.gray[50], colors.darkGray[700])};
1584
1748
  display: flex;
1585
1749
  flex-direction: column;
1750
+ & * {
1751
+ font-family: 'Inter', sans-serif;
1752
+ }
1586
1753
  `,
1587
1754
  dragHandle: css`
1588
1755
  position: absolute;
1589
1756
  transition: background-color 0.125s ease;
1590
1757
  &:hover {
1591
- background-color: ${colors.purple[400]}${alpha[90]};
1758
+ background-color: ${colors.purple[400]}${t('', alpha[90])};
1592
1759
  }
1593
1760
  z-index: 4;
1594
1761
  `,
@@ -1622,7 +1789,7 @@ const getStyles = () => {
1622
1789
  align-items: center;
1623
1790
  padding: ${tokens.size[2]} ${tokens.size[2.5]};
1624
1791
  gap: ${tokens.size[3]};
1625
- border-bottom: ${colors.darkGray[500]} 1px solid;
1792
+ border-bottom: ${t(colors.gray[300], colors.darkGray[500])} 1px solid;
1626
1793
  align-items: center;
1627
1794
  & > button {
1628
1795
  padding: 0;
@@ -1649,11 +1816,15 @@ const getStyles = () => {
1649
1816
  font-weight: ${font.weight.bold};
1650
1817
  line-height: ${font.lineHeight.xs};
1651
1818
  white-space: nowrap;
1819
+ color: ${t(colors.gray[600], colors.gray[300])};
1652
1820
  `,
1653
1821
  queryFlavorLogo: css`
1654
1822
  font-weight: ${font.weight.semibold};
1655
1823
  font-size: ${font.size.xs};
1656
- background: linear-gradient(to right, #dd524b, #e9a03b);
1824
+ background: linear-gradient(
1825
+ to right,
1826
+ ${t('#ea4037, #ff9b11', '#dd524b, #e9a03b')}
1827
+ );
1657
1828
  background-clip: text;
1658
1829
  -webkit-background-clip: text;
1659
1830
  line-height: 1;
@@ -1668,14 +1839,17 @@ const getStyles = () => {
1668
1839
  queryStatusTag: css`
1669
1840
  display: flex;
1670
1841
  gap: ${tokens.size[1.5]};
1671
- background: ${colors.darkGray[500]};
1842
+ box-sizing: border-box;
1843
+ height: ${tokens.size[6.5]};
1844
+ background: ${t(colors.gray[50], colors.darkGray[500])};
1845
+ color: ${t(colors.gray[700], colors.gray[300])};
1672
1846
  border-radius: ${tokens.border.radius.sm};
1673
1847
  font-size: ${font.size.sm};
1674
1848
  padding: ${tokens.size[1]};
1675
- padding-left: ${tokens.size[2]};
1849
+ padding-left: ${tokens.size[1.5]};
1676
1850
  align-items: center;
1677
1851
  font-weight: ${font.weight.medium};
1678
- border: none;
1852
+ border: ${t('1px solid ' + colors.gray[300], '1px solid transparent')};
1679
1853
  user-select: none;
1680
1854
  position: relative;
1681
1855
  &:focus-visible {
@@ -1692,8 +1866,8 @@ const getStyles = () => {
1692
1866
  display: flex;
1693
1867
  align-items: center;
1694
1868
  justify-content: center;
1695
- color: ${colors.gray[400]};
1696
- background-color: ${colors.darkGray[300]};
1869
+ color: ${t(colors.gray[500], colors.gray[400])};
1870
+ background-color: ${t(colors.gray[200], colors.darkGray[300])};
1697
1871
  border-radius: 2px;
1698
1872
  font-variant-numeric: tabular-nums;
1699
1873
  height: ${tokens.size[4.5]};
@@ -1701,15 +1875,15 @@ const getStyles = () => {
1701
1875
  statusTooltip: css`
1702
1876
  position: absolute;
1703
1877
  z-index: 1;
1704
- background-color: ${colors.darkGray[500]};
1878
+ background-color: ${t(colors.gray[50], colors.darkGray[500])};
1705
1879
  top: 100%;
1706
1880
  left: 50%;
1707
1881
  transform: translate(-50%, calc(${tokens.size[2]}));
1708
1882
  padding: ${tokens.size[0.5]} ${tokens.size[2]};
1709
- border-radius: ${tokens.border.radius.md};
1883
+ border-radius: ${tokens.border.radius.sm};
1710
1884
  font-size: ${font.size.xs};
1711
- border: 1px solid ${colors.gray[600]};
1712
- color: ${tokens.colors['gray'][300]};
1885
+ border: 1px solid ${t(colors.gray[400], colors.gray[600])};
1886
+ color: ${t(colors['gray'][600], colors['gray'][300])};
1713
1887
 
1714
1888
  &::before {
1715
1889
  top: 0px;
@@ -1718,7 +1892,8 @@ const getStyles = () => {
1718
1892
  left: 50%;
1719
1893
  transform: translate(-50%, -100%);
1720
1894
  position: absolute;
1721
- border-color: transparent transparent ${colors.gray[600]} transparent;
1895
+ border-color: transparent transparent
1896
+ ${t(colors.gray[400], colors.gray[600])} transparent;
1722
1897
  border-style: solid;
1723
1898
  border-width: 7px;
1724
1899
  /* transform: rotate(180deg); */
@@ -1729,17 +1904,14 @@ const getStyles = () => {
1729
1904
  content: ' ';
1730
1905
  display: block;
1731
1906
  left: 50%;
1732
- transform: translate(-50%, calc(-100% + 2.5px));
1907
+ transform: translate(-50%, calc(-100% + 2px));
1733
1908
  position: absolute;
1734
- border-color: transparent transparent ${colors.darkGray[500]}
1735
- transparent;
1909
+ border-color: transparent transparent
1910
+ ${t(colors.gray[100], colors.darkGray[500])} transparent;
1736
1911
  border-style: solid;
1737
1912
  border-width: 7px;
1738
1913
  }
1739
1914
  `,
1740
- selectedQueryRow: css`
1741
- background-color: ${colors.darkGray[500]};
1742
- `,
1743
1915
  filtersContainer: css`
1744
1916
  display: flex;
1745
1917
  gap: ${tokens.size[2]};
@@ -1748,47 +1920,52 @@ const getStyles = () => {
1748
1920
  padding: ${tokens.size[0.5]} ${tokens.size[2]};
1749
1921
  padding-right: ${tokens.size[1.5]};
1750
1922
  border-radius: ${tokens.border.radius.sm};
1751
- background-color: ${colors.darkGray[400]};
1923
+ background-color: ${t(colors.gray[100], colors.darkGray[400])};
1924
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
1925
+ color: ${t(colors.gray[700], colors.gray[300])};
1752
1926
  font-size: ${font.size.xs};
1753
1927
  display: flex;
1754
1928
  align-items: center;
1755
1929
  line-height: ${font.lineHeight.sm};
1756
1930
  gap: ${tokens.size[1.5]};
1757
1931
  max-width: 160px;
1758
- border: 1px solid ${colors.darkGray[200]};
1759
1932
  &:focus-visible {
1760
1933
  outline-offset: 2px;
1761
1934
  border-radius: ${border.radius.xs};
1762
1935
  outline: 2px solid ${colors.blue[800]};
1763
1936
  }
1937
+ & svg {
1938
+ color: ${t(colors.gray[500], colors.gray[400])};
1939
+ }
1764
1940
  }
1765
1941
  `,
1766
1942
  filterInput: css`
1767
- padding: ${tokens.size[0.5]} ${tokens.size[2]};
1943
+ padding: ${size[0.5]} ${size[2]};
1768
1944
  border-radius: ${tokens.border.radius.sm};
1769
- background-color: ${colors.darkGray[400]};
1945
+ background-color: ${t(colors.gray[100], colors.darkGray[400])};
1770
1946
  display: flex;
1771
1947
  box-sizing: content-box;
1772
1948
  align-items: center;
1773
1949
  gap: ${tokens.size[1.5]};
1774
1950
  max-width: 160px;
1775
1951
  min-width: 100px;
1776
- border: 1px solid ${colors.darkGray[200]};
1952
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
1777
1953
  height: min-content;
1954
+ color: ${t(colors.gray[600], colors.gray[400])};
1778
1955
  & > svg {
1779
- width: ${tokens.size[3]};
1780
- height: ${tokens.size[3]};
1956
+ width: ${size[3]};
1957
+ height: ${size[3]};
1781
1958
  }
1782
1959
  & input {
1783
1960
  font-size: ${font.size.xs};
1784
1961
  width: 100%;
1785
- background-color: ${colors.darkGray[400]};
1962
+ background-color: ${t(colors.gray[100], colors.darkGray[400])};
1786
1963
  border: none;
1787
1964
  padding: 0;
1788
1965
  line-height: ${font.lineHeight.sm};
1789
- color: ${colors.gray[300]};
1966
+ color: ${t(colors.gray[700], colors.gray[300])};
1790
1967
  &::placeholder {
1791
- color: ${colors.gray[300]};
1968
+ color: ${t(colors.gray[700], colors.gray[300])};
1792
1969
  }
1793
1970
  &:focus {
1794
1971
  outline: none;
@@ -1804,24 +1981,26 @@ const getStyles = () => {
1804
1981
  filterSelect: css`
1805
1982
  padding: ${tokens.size[0.5]} ${tokens.size[2]};
1806
1983
  border-radius: ${tokens.border.radius.sm};
1807
- background-color: ${colors.darkGray[400]};
1984
+ background-color: ${t(colors.gray[100], colors.darkGray[400])};
1808
1985
  display: flex;
1809
1986
  align-items: center;
1810
1987
  gap: ${tokens.size[1.5]};
1811
1988
  box-sizing: content-box;
1812
1989
  max-width: 160px;
1813
- border: 1px solid ${colors.darkGray[200]};
1990
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
1814
1991
  height: min-content;
1815
1992
  & > svg {
1993
+ color: ${t(colors.gray[600], colors.gray[400])};
1816
1994
  width: ${tokens.size[2]};
1817
1995
  height: ${tokens.size[2]};
1818
1996
  }
1819
1997
  & > select {
1820
1998
  appearance: none;
1999
+ color: ${t(colors.gray[700], colors.gray[300])};
1821
2000
  min-width: 100px;
1822
2001
  line-height: ${font.lineHeight.sm};
1823
2002
  font-size: ${font.size.xs};
1824
- background-color: ${colors.darkGray[400]};
2003
+ background-color: ${t(colors.gray[100], colors.darkGray[400])};
1825
2004
  border: none;
1826
2005
  &:focus {
1827
2006
  outline: none;
@@ -1839,7 +2018,8 @@ const getStyles = () => {
1839
2018
  `,
1840
2019
  actionsBtn: css`
1841
2020
  border-radius: ${tokens.border.radius.sm};
1842
- background-color: ${colors.darkGray[400]};
2021
+ background-color: ${t(colors.gray[100], colors.darkGray[400])};
2022
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
1843
2023
  width: 1.625rem;
1844
2024
  height: 1.625rem;
1845
2025
  justify-content: center;
@@ -1847,13 +2027,13 @@ const getStyles = () => {
1847
2027
  align-items: center;
1848
2028
  gap: ${tokens.size[1.5]};
1849
2029
  max-width: 160px;
1850
- border: 1px solid ${colors.darkGray[200]};
1851
2030
  cursor: pointer;
1852
2031
  padding: 0;
1853
2032
  &:hover {
1854
- background-color: ${colors.darkGray[500]};
2033
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
1855
2034
  }
1856
2035
  & svg {
2036
+ color: ${t(colors.gray[700], colors.gray[300])};
1857
2037
  width: ${tokens.size[3]};
1858
2038
  height: ${tokens.size[3]};
1859
2039
  }
@@ -1863,6 +2043,12 @@ const getStyles = () => {
1863
2043
  outline: 2px solid ${colors.blue[800]};
1864
2044
  }
1865
2045
  `,
2046
+ actionsBtnOffline: css`
2047
+ & svg {
2048
+ stroke: ${t(colors.yellow[700], colors.yellow[500])};
2049
+ fill: ${t(colors.yellow[700], colors.yellow[500])};
2050
+ }
2051
+ `,
1866
2052
  overflowQueryContainer: css`
1867
2053
  flex: 1;
1868
2054
  overflow-y: auto;
@@ -1875,9 +2061,11 @@ const getStyles = () => {
1875
2061
  display: flex;
1876
2062
  align-items: center;
1877
2063
  padding: 0;
1878
- background-color: inherit;
1879
2064
  border: none;
1880
2065
  cursor: pointer;
2066
+ color: ${t(colors.gray[700], colors.gray[300])};
2067
+ background-color: ${t(colors.gray[50], colors.darkGray[700])};
2068
+ line-height: 1;
1881
2069
  &:focus {
1882
2070
  outline: none;
1883
2071
  }
@@ -1887,7 +2075,7 @@ const getStyles = () => {
1887
2075
  outline: 2px solid ${colors.blue[800]};
1888
2076
  }
1889
2077
  &:hover .tsqd-query-hash {
1890
- background-color: ${colors.darkGray[600]};
2078
+ background-color: ${t(colors.gray[200], colors.darkGray[600])};
1891
2079
  }
1892
2080
 
1893
2081
  & .tsqd-query-observer-count {
@@ -1902,7 +2090,7 @@ const getStyles = () => {
1902
2090
  font-weight: ${font.weight.medium};
1903
2091
  border-bottom-width: 1px;
1904
2092
  border-bottom-style: solid;
1905
- border-bottom: 1px solid ${colors.darkGray[700]};
2093
+ border-bottom: 1px solid ${t(colors.gray[300], colors.darkGray[700])};
1906
2094
  }
1907
2095
  & .tsqd-query-hash {
1908
2096
  user-select: text;
@@ -1913,7 +2101,7 @@ const getStyles = () => {
1913
2101
  flex: 1;
1914
2102
  padding: ${tokens.size[1]} ${tokens.size[2]};
1915
2103
  font-family: 'Menlo', 'Fira Code', monospace;
1916
- border-bottom: 1px solid ${colors.darkGray[400]};
2104
+ border-bottom: 1px solid ${t(colors.gray[300], colors.darkGray[400])};
1917
2105
  text-align: left;
1918
2106
  text-overflow: clip;
1919
2107
  word-break: break-word;
@@ -1924,15 +2112,20 @@ const getStyles = () => {
1924
2112
  display: flex;
1925
2113
  align-items: center;
1926
2114
  padding: 0 ${tokens.size[2]};
1927
- color: ${colors.gray[300]};
1928
- background-color: ${colors.darkGray[600]};
1929
- border-bottom: 1px solid ${colors.darkGray[400]};
2115
+ color: ${t(colors.gray[800], colors.gray[300])};
2116
+ background-color: ${t(colors.gray[300], colors.darkGray[600])};
2117
+ border-bottom: 1px solid ${t(colors.gray[300], colors.darkGray[400])};
1930
2118
  font-size: ${font.size.xs};
1931
2119
  }
1932
2120
  `,
2121
+ selectedQueryRow: css`
2122
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
2123
+ `,
1933
2124
  detailsContainer: css`
1934
2125
  flex: 1 1 700px;
1935
- background-color: ${colors.darkGray[700]};
2126
+ background-color: ${t(colors.gray[50], colors.darkGray[700])};
2127
+ color: ${t(colors.gray[700], colors.gray[300])};
2128
+ font-family: 'Inter', sans-serif;
1936
2129
  display: flex;
1937
2130
  flex-direction: column;
1938
2131
  overflow-y: auto;
@@ -1940,10 +2133,11 @@ const getStyles = () => {
1940
2133
  text-align: left;
1941
2134
  `,
1942
2135
  detailsHeader: css`
2136
+ font-family: 'Inter', sans-serif;
1943
2137
  position: sticky;
1944
2138
  top: 0;
1945
2139
  z-index: 2;
1946
- background-color: ${colors.darkGray[600]};
2140
+ background-color: ${t(colors.gray[200], colors.darkGray[600])};
1947
2141
  padding: ${tokens.size[1.5]} ${tokens.size[2]};
1948
2142
  font-weight: ${font.weight.medium};
1949
2143
  font-size: ${font.size.xs};
@@ -1976,6 +2170,10 @@ const getStyles = () => {
1976
2170
  font-size: ${font.size.xs};
1977
2171
  line-height: ${font.lineHeight.xs};
1978
2172
  }
2173
+
2174
+ & pre {
2175
+ margin: 0;
2176
+ }
1979
2177
  `,
1980
2178
  queryDetailsStatus: css`
1981
2179
  border: 1px solid ${colors.darkGray[200]};
@@ -1990,12 +2188,13 @@ const getStyles = () => {
1990
2188
  gap: ${tokens.size[2]};
1991
2189
  padding: 0px ${tokens.size[2]};
1992
2190
  & > button {
2191
+ font-family: 'Inter', sans-serif;
1993
2192
  font-size: ${font.size.xs};
1994
2193
  padding: ${tokens.size[1]} ${tokens.size[2]};
1995
2194
  display: flex;
1996
2195
  border-radius: ${tokens.border.radius.sm};
1997
- border: 1px solid ${colors.darkGray[400]};
1998
- background-color: ${colors.darkGray[600]};
2196
+ background-color: ${t(colors.gray[100], colors.darkGray[600])};
2197
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[400])};
1999
2198
  align-items: center;
2000
2199
  gap: ${tokens.size[2]};
2001
2200
  font-weight: ${font.weight.medium};
@@ -2007,7 +2206,7 @@ const getStyles = () => {
2007
2206
  outline: 2px solid ${colors.blue[800]};
2008
2207
  }
2009
2208
  &:hover {
2010
- background-color: ${colors.darkGray[500]};
2209
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
2011
2210
  }
2012
2211
 
2013
2212
  &:disabled {
@@ -2028,17 +2227,17 @@ const getStyles = () => {
2028
2227
  display: flex;
2029
2228
  border-radius: ${tokens.border.radius.sm};
2030
2229
  overflow: hidden;
2031
- border: 1px solid ${colors.darkGray[400]};
2032
- background-color: ${colors.darkGray[600]};
2230
+ background-color: ${t(colors.gray[100], colors.darkGray[600])};
2231
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[400])};
2033
2232
  align-items: center;
2034
2233
  gap: ${tokens.size[2]};
2035
2234
  font-weight: ${font.weight.medium};
2036
2235
  line-height: ${font.lineHeight.sm};
2037
- color: ${tokens.colors.red[400]};
2236
+ color: ${t(colors.red[500], colors.red[400])};
2038
2237
  cursor: pointer;
2039
2238
  position: relative;
2040
2239
  &:hover {
2041
- background-color: ${colors.darkGray[500]};
2240
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
2042
2241
  }
2043
2242
  & > span {
2044
2243
  width: ${size[1.5]};
@@ -2079,10 +2278,10 @@ const getStyles = () => {
2079
2278
  flex-direction: column;
2080
2279
  gap: ${size[0.5]};
2081
2280
  border-radius: ${tokens.border.radius.sm};
2082
- border: 1px solid ${colors.gray[700]};
2083
- background-color: ${colors.darkGray[600]};
2281
+ border: 1px solid ${t(colors.gray[300], colors.gray[700])};
2282
+ background-color: ${t(colors.gray[50], colors.darkGray[600])};
2084
2283
  font-size: ${font.size.xs};
2085
- color: ${colors.gray[300]};
2284
+ color: ${t(colors.gray[700], colors.gray[300])};
2086
2285
  z-index: 99999;
2087
2286
  min-width: 120px;
2088
2287
  padding: ${size[0.5]};
@@ -2092,17 +2291,19 @@ const getStyles = () => {
2092
2291
  align-items: center;
2093
2292
  justify-content: space-between;
2094
2293
  border-radius: ${tokens.border.radius.xs};
2095
- padding: ${tokens.size[0.5]} ${tokens.size[1]};
2294
+ padding: ${tokens.size[1]} ${tokens.size[1]};
2096
2295
  cursor: pointer;
2097
2296
  background-color: transparent;
2098
2297
  border: none;
2298
+ color: ${t(colors.gray[700], colors.gray[300])};
2099
2299
  & svg {
2300
+ color: ${t(colors.gray[600], colors.gray[400])};
2100
2301
  transform: rotate(-90deg);
2101
2302
  width: ${tokens.size[2]};
2102
2303
  height: ${tokens.size[2]};
2103
2304
  }
2104
2305
  &:hover {
2105
- background-color: ${colors.darkGray[500]};
2306
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
2106
2307
  }
2107
2308
  &:focus-visible {
2108
2309
  outline-offset: 2px;
@@ -2114,30 +2315,46 @@ const getStyles = () => {
2114
2315
  }
2115
2316
  `,
2116
2317
  settingsMenuHeader: css`
2117
- padding: ${tokens.size[0.5]} ${tokens.size[1]};
2318
+ padding: ${tokens.size[1]} ${tokens.size[1]};
2118
2319
  font-weight: ${font.weight.medium};
2119
- border-bottom: 1px solid ${colors.darkGray[400]};
2120
- color: ${colors.gray[400]};
2320
+ border-bottom: 1px solid ${t(colors.gray[300], colors.darkGray[400])};
2321
+ color: ${t(colors.gray[500], colors.gray[400])};
2121
2322
  font-size: ${font.size['xs']};
2122
2323
  `,
2123
2324
  settingsSubButton: css`
2124
2325
  display: flex;
2125
2326
  align-items: center;
2126
2327
  justify-content: space-between;
2127
- color: ${colors.gray[300]};
2328
+ color: ${t(colors.gray[700], colors.gray[300])};
2128
2329
  font-size: ${font.size['xs']};
2129
2330
  border-radius: ${tokens.border.radius.xs};
2130
- padding: ${tokens.size[0.5]} ${tokens.size[1]};
2331
+ padding: ${tokens.size[1]} ${tokens.size[1]};
2131
2332
  cursor: pointer;
2132
2333
  background-color: transparent;
2133
2334
  border: none;
2335
+ & svg {
2336
+ color: ${t(colors.gray[600], colors.gray[400])};
2337
+ }
2134
2338
  &:hover {
2135
- background-color: ${colors.darkGray[500]};
2339
+ background-color: ${t(colors.gray[200], colors.darkGray[500])};
2136
2340
  }
2137
2341
  &:focus-visible {
2138
2342
  outline-offset: 2px;
2139
2343
  outline: 2px solid ${colors.blue[800]};
2140
2344
  }
2141
2345
  `,
2346
+ themeSelectedButton: css`
2347
+ background-color: ${t(colors.purple[100], colors.purple[900])};
2348
+ color: ${t(colors.purple[700], colors.purple[300])};
2349
+ & svg {
2350
+ color: ${t(colors.purple[700], colors.purple[300])};
2351
+ }
2352
+ &:hover {
2353
+ background-color: ${t(colors.purple[100], colors.purple[900])};
2354
+ }
2355
+ `,
2142
2356
  }
2143
2357
  }
2358
+
2359
+ const lightStyles = stylesFactory('light')
2360
+ const darkStyles = stylesFactory('dark')