Skip to content

Commit 48fe741

Browse files
authored
feat: allow editing of boolean values (#6131)
1 parent dbfe8a0 commit 48fe741

File tree

2 files changed

+111
-21
lines changed

2 files changed

+111
-21
lines changed

packages/query-devtools/src/Explorer.tsx

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
displayValue,
1010
updateNestedDataByPath,
1111
} from './utils'
12-
import { CopiedCopier, Copier, ErrorCopier, List, Trash } from './icons'
12+
import { Check, CopiedCopier, Copier, ErrorCopier, List, Trash } from './icons'
1313
import { useQueryDevtoolsContext } from './Context'
1414
import type { Query } from '@tanstack/query-core'
1515

@@ -171,6 +171,34 @@ const DeleteItemButton = (props: {
171171
)
172172
}
173173

174+
const ToggleValueButton = (props: {
175+
dataPath: Array<string>
176+
activeQuery: Query
177+
value: boolean
178+
}) => {
179+
const styles = getStyles()
180+
const queryClient = useQueryDevtoolsContext().client
181+
182+
return (
183+
<button
184+
class={cx(styles.actionButton)}
185+
title={'Toggle value'}
186+
aria-label={'Toggle value'}
187+
onClick={() => {
188+
const oldData = props.activeQuery.state.data
189+
const newData = updateNestedDataByPath(
190+
oldData,
191+
props.dataPath,
192+
!props.value,
193+
)
194+
queryClient.setQueryData(props.activeQuery.queryKey, newData)
195+
}}
196+
>
197+
<Check checked={props.value} />
198+
</button>
199+
)
200+
}
201+
174202
type ExplorerProps = {
175203
editable?: boolean
176204
label: string
@@ -359,30 +387,53 @@ export default function Explorer(props: ExplorerProps) {
359387
when={
360388
props.editable &&
361389
props.activeQuery !== undefined &&
362-
(type() === 'string' || type() === 'number')
390+
(type() === 'string' ||
391+
type() === 'number' ||
392+
type() === 'boolean')
363393
}
364394
fallback={
365395
<span class={styles.value}>{displayValue(props.value)}</span>
366396
}
367397
>
368-
<input
369-
type={type() === 'number' ? 'number' : 'text'}
370-
class={cx(styles.value, styles.editableInput)}
371-
value={props.value as string | number}
372-
onChange={(changeEvent) => {
373-
const oldData = props.activeQuery!.state.data
374-
375-
const newData = updateNestedDataByPath(
376-
oldData,
377-
currentDataPath,
378-
type() === 'number'
379-
? changeEvent.target.valueAsNumber
380-
: changeEvent.target.value,
381-
)
382-
383-
queryClient.setQueryData(props.activeQuery!.queryKey, newData)
384-
}}
385-
/>
398+
<Show
399+
when={
400+
props.editable &&
401+
props.activeQuery !== undefined &&
402+
(type() === 'string' || type() === 'number')
403+
}
404+
>
405+
<input
406+
type={type() === 'number' ? 'number' : 'text'}
407+
class={cx(styles.value, styles.editableInput)}
408+
value={props.value as string | number}
409+
onChange={(changeEvent) => {
410+
const oldData = props.activeQuery!.state.data
411+
412+
const newData = updateNestedDataByPath(
413+
oldData,
414+
currentDataPath,
415+
type() === 'number'
416+
? changeEvent.target.valueAsNumber
417+
: changeEvent.target.value,
418+
)
419+
420+
queryClient.setQueryData(props.activeQuery!.queryKey, newData)
421+
}}
422+
/>
423+
</Show>
424+
425+
<Show when={type() === 'boolean'}>
426+
<span
427+
class={cx(styles.value, styles.actions, styles.editableInput)}
428+
>
429+
<ToggleValueButton
430+
activeQuery={props.activeQuery!}
431+
dataPath={currentDataPath}
432+
value={props.value as boolean}
433+
/>
434+
{displayValue(props.value)}
435+
</span>
436+
</Show>
386437
</Show>
387438

388439
<Show
@@ -483,17 +534,19 @@ const getStyles = () => {
483534
actions: css`
484535
display: inline-flex;
485536
gap: ${size[2]};
537+
align-items: center;
486538
`,
487539
row: css`
488540
display: inline-flex;
489541
gap: ${size[2]};
490542
width: 100%;
491543
margin-bottom: ${size[0.5]};
492544
line-height: 1.125rem;
545+
align-items: center;
493546
`,
494547
editableInput: css`
495548
border: none;
496-
padding: 0px ${size[1]};
549+
padding: ${size[0.5]} ${size[1]};
497550
flex-grow: 1;
498551
background-color: ${colors.gray[900]};
499552
@@ -516,6 +569,7 @@ const getStyles = () => {
516569
517570
&:hover svg {
518571
.copier,
572+
.check,
519573
.list {
520574
stroke: ${colors.gray[500]} !important;
521575
}

packages/query-devtools/src/icons/index.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,42 @@ export function List() {
290290
)
291291
}
292292

293+
export function Check(props: { checked: boolean }) {
294+
return (
295+
<svg
296+
width="24"
297+
height="24"
298+
viewBox="0 0 24 24"
299+
fill="none"
300+
stroke="#98A2B3"
301+
stroke-width="2"
302+
xmlns="http://www.w3.org/2000/svg"
303+
>
304+
<rect x="2" y="2" width="20" height="20" rx="2" class="check" />
305+
{props.checked && (
306+
<g>
307+
<line
308+
transform="rotate(45 7.18873 14.6316)"
309+
x1="3.56453"
310+
y1="14.63158"
311+
x2="10.81294"
312+
y2="14.63158"
313+
class="check"
314+
/>
315+
<line
316+
transform="rotate(-45 13.9674 11.5826)"
317+
x1="6.02012"
318+
y1="11.58263"
319+
x2="21.91469"
320+
y2="11.58263"
321+
class="check"
322+
/>
323+
</g>
324+
)}
325+
</svg>
326+
)
327+
}
328+
293329
export function TanstackLogo() {
294330
return (
295331
<svg version="1.0" viewBox="0 0 633 633">

0 commit comments

Comments
 (0)