Skip to content

Commit 63d3526

Browse files
committed
fix: issue with responsiveness in jsontree
1 parent cd84251 commit 63d3526

2 files changed

Lines changed: 95 additions & 116 deletions

File tree

.changeset/wicked-cobras-peel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/devtools-ui': patch
3+
---
4+
5+
fix responsiveness in jsontree

packages/devtools-ui/src/components/tree.tsx

Lines changed: 90 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export function JsonTree<TData, TName extends CollapsiblePaths<TData>>(props: {
1010
defaultExpansionDepth?: number
1111
collapsePaths?: Array<TName>
1212
}) {
13+
1314
return (
1415
<JsonValue
1516
isRoot
@@ -36,94 +37,76 @@ function JsonValue(props: {
3637
collapsePaths?: Array<string>
3738
path: string
3839
}) {
39-
const {
40-
value,
41-
keyName,
42-
isRoot = false,
43-
isLastKey,
44-
copyable,
45-
defaultExpansionDepth,
46-
depth,
47-
collapsePaths,
48-
path,
49-
} = props
40+
5041
const styles = useStyles()
5142

5243
return (
53-
<span class={styles().tree.valueContainer(isRoot)}>
54-
{keyName && typeof value !== 'object' && !Array.isArray(value) && (
55-
<span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>
44+
<span class={styles().tree.valueContainer(props.isRoot ?? false)}>
45+
{props.keyName && typeof props.value !== 'object' && !Array.isArray(props.value) && (
46+
<span class={styles().tree.valueKey}>&quot;{props.keyName}&quot;: </span>
5647
)}
5748
{(() => {
58-
if (typeof value === 'string') {
49+
if (typeof props.value === 'string') {
5950
return (
60-
<span class={styles().tree.valueString}>&quot;{value}&quot;</span>
51+
<span class={styles().tree.valueString}>&quot;{props.value}&quot;</span>
6152
)
6253
}
63-
if (typeof value === 'number') {
64-
return <span class={styles().tree.valueNumber}>{value}</span>
54+
if (typeof props.value === 'number') {
55+
return <span class={styles().tree.valueNumber}>{props.value}</span>
6556
}
66-
if (typeof value === 'boolean') {
67-
return <span class={styles().tree.valueBoolean}>{String(value)}</span>
57+
if (typeof props.value === 'boolean') {
58+
return <span class={styles().tree.valueBoolean}>{String(props.value)}</span>
6859
}
69-
if (value === null) {
60+
if (props.value === null) {
7061
return <span class={styles().tree.valueNull}>null</span>
7162
}
72-
if (value === undefined) {
63+
if (props.value === undefined) {
7364
return <span class={styles().tree.valueNull}>undefined</span>
7465
}
75-
if (typeof value === 'function') {
66+
if (typeof props.value === 'function') {
7667
return (
77-
<span class={styles().tree.valueFunction}>{String(value)}</span>
68+
<span class={styles().tree.valueFunction}>{String(props.value)}</span>
7869
)
7970
}
80-
if (Array.isArray(value)) {
71+
if (Array.isArray(props.value)) {
8172
return (
8273
<ArrayValue
83-
defaultExpansionDepth={defaultExpansionDepth}
84-
depth={depth}
85-
copyable={copyable}
86-
keyName={keyName}
87-
value={value}
88-
collapsePaths={collapsePaths}
89-
path={path}
74+
defaultExpansionDepth={props.defaultExpansionDepth}
75+
depth={props.depth}
76+
copyable={props.copyable}
77+
keyName={props.keyName}
78+
value={props.value}
79+
collapsePaths={props.collapsePaths}
80+
path={props.path}
9081
/>
9182
)
9283
}
93-
if (typeof value === 'object') {
84+
if (typeof props.value === 'object') {
9485
return (
9586
<ObjectValue
96-
defaultExpansionDepth={defaultExpansionDepth}
97-
depth={depth}
98-
copyable={copyable}
99-
keyName={keyName}
100-
value={value}
101-
collapsePaths={collapsePaths}
102-
path={path}
87+
defaultExpansionDepth={props.defaultExpansionDepth}
88+
depth={props.depth}
89+
copyable={props.copyable}
90+
keyName={props.keyName}
91+
value={props.value}
92+
collapsePaths={props.collapsePaths}
93+
path={props.path}
10394
/>
10495
)
10596
}
10697
return <span />
10798
})()}
108-
{copyable && (
99+
{props.copyable && (
109100
<div class={clsx(styles().tree.actions, 'actions')}>
110-
<CopyButton value={value} />
101+
<CopyButton value={props.value} />
111102
</div>
112103
)}
113-
{isLastKey || isRoot ? '' : <span>,</span>}
104+
{props.isLastKey || props.isRoot ? '' : <span>,</span>}
114105
</span>
115106
)
116107
}
117108

118-
const ArrayValue = ({
119-
value,
120-
keyName,
121-
copyable,
122-
defaultExpansionDepth,
123-
depth,
124-
collapsePaths,
125-
path,
126-
}: {
109+
const ArrayValue = (props: {
127110
value: Array<any>
128111
copyable?: boolean
129112
keyName?: string
@@ -135,15 +118,15 @@ const ArrayValue = ({
135118
const styles = useStyles()
136119

137120
const [expanded, setExpanded] = createSignal(
138-
depth <= defaultExpansionDepth && !collapsePaths?.includes(path),
121+
props.depth <= props.defaultExpansionDepth && !props.collapsePaths?.includes(props.path),
139122
)
140123

141-
if (value.length === 0) {
124+
if (props.value.length === 0) {
142125
return (
143126
<span class={styles().tree.expanderContainer}>
144-
{keyName && (
127+
{props.keyName && (
145128
<span class={clsx(styles().tree.valueKey, styles().tree.collapsible)}>
146-
&quot;{keyName}&quot;:{' '}
129+
&quot;{props.keyName}&quot;:{' '}
147130
</span>
148131
)}
149132

@@ -158,7 +141,7 @@ const ArrayValue = ({
158141
expanded={expanded()}
159142
/>
160143

161-
{keyName && (
144+
{props.keyName && (
162145
<span
163146
onclick={(e) => {
164147
e.stopPropagation()
@@ -167,27 +150,27 @@ const ArrayValue = ({
167150
}}
168151
class={clsx(styles().tree.valueKey, styles().tree.collapsible)}
169152
>
170-
&quot;{keyName}&quot;:{' '}
171-
<span class={styles().tree.info}>{value.length} items</span>
153+
&quot;{props.keyName}&quot;:{' '}
154+
<span class={styles().tree.info}>{props.value.length} items</span>
172155
</span>
173156
)}
174157

175158
<span class={styles().tree.valueBraces}>[</span>
176159

177160
<Show when={expanded()}>
178-
<span class={styles().tree.expandedLine(Boolean(keyName))}>
179-
<For each={value}>
161+
<span class={styles().tree.expandedLine(Boolean(props.keyName))}>
162+
<For each={props.value}>
180163
{(item, i) => {
181-
const isLastKey = i() === value.length - 1
164+
const isLastKey = i() === props.value.length - 1
182165
return (
183166
<JsonValue
184-
copyable={copyable}
167+
copyable={props.copyable}
185168
value={item}
186169
isLastKey={isLastKey}
187-
defaultExpansionDepth={defaultExpansionDepth}
188-
depth={depth + 1}
189-
collapsePaths={collapsePaths}
190-
path={path ? `${path}[${i()}]` : `[${i()}]`}
170+
defaultExpansionDepth={props.defaultExpansionDepth}
171+
depth={props.depth + 1}
172+
collapsePaths={props.collapsePaths}
173+
path={props.path ? `${props.path}[${i()}]` : `[${i()}]`}
191174
/>
192175
)
193176
}}
@@ -212,15 +195,7 @@ const ArrayValue = ({
212195
)
213196
}
214197

215-
const ObjectValue = ({
216-
value,
217-
keyName,
218-
copyable,
219-
defaultExpansionDepth,
220-
depth,
221-
collapsePaths,
222-
path,
223-
}: {
198+
const ObjectValue = (props: {
224199
value: Record<string, any>
225200
keyName?: string
226201
copyable?: boolean
@@ -232,18 +207,18 @@ const ObjectValue = ({
232207
const styles = useStyles()
233208

234209
const [expanded, setExpanded] = createSignal(
235-
depth <= defaultExpansionDepth && !collapsePaths?.includes(path),
210+
props.depth <= props.defaultExpansionDepth && !props.collapsePaths?.includes(props.path),
236211
)
237212

238-
const keys = Object.keys(value)
213+
const keys = Object.keys(props.value)
239214
const lastKeyName = keys[keys.length - 1]
240215

241216
if (keys.length === 0) {
242217
return (
243218
<span class={styles().tree.expanderContainer}>
244-
{keyName && (
219+
{props.keyName && (
245220
<span class={clsx(styles().tree.valueKey, styles().tree.collapsible)}>
246-
&quot;{keyName}&quot;:{' '}
221+
&quot;{props.keyName}&quot;:{' '}
247222
</span>
248223
)}
249224

@@ -254,14 +229,14 @@ const ObjectValue = ({
254229

255230
return (
256231
<span class={styles().tree.expanderContainer}>
257-
{keyName && (
232+
{props.keyName && (
258233
<Expander
259234
onClick={() => setExpanded(!expanded())}
260235
expanded={expanded()}
261236
/>
262237
)}
263238

264-
{keyName && (
239+
{props.keyName && (
265240
<span
266241
onClick={(e) => {
267242
e.stopPropagation()
@@ -270,27 +245,27 @@ const ObjectValue = ({
270245
}}
271246
class={clsx(styles().tree.valueKey, styles().tree.collapsible)}
272247
>
273-
&quot;{keyName}&quot;:{' '}
248+
&quot;{props.keyName}&quot;:{' '}
274249
<span class={styles().tree.info}>{keys.length} items</span>
275250
</span>
276251
)}
277252

278253
<span class={styles().tree.valueBraces}>{'{'}</span>
279254

280255
<Show when={expanded()}>
281-
<span class={styles().tree.expandedLine(Boolean(keyName))}>
256+
<span class={styles().tree.expandedLine(Boolean(props.keyName))}>
282257
<For each={keys}>
283258
{(k) => (
284259
<>
285260
<JsonValue
286-
value={value[k]}
261+
value={props.value[k]}
287262
keyName={k}
288263
isLastKey={lastKeyName === k}
289-
copyable={copyable}
290-
defaultExpansionDepth={defaultExpansionDepth}
291-
depth={depth + 1}
292-
collapsePaths={collapsePaths}
293-
path={`${path}${path ? '.' : ''}${k}`}
264+
copyable={props.copyable}
265+
defaultExpansionDepth={props.defaultExpansionDepth}
266+
depth={props.depth + 1}
267+
collapsePaths={props.collapsePaths}
268+
path={`${props.path}${props.path ? '.' : ''}${k}`}
294269
/>
295270
</>
296271
)}
@@ -326,34 +301,33 @@ const CopyButton = (props: { value: unknown }) => {
326301
<button
327302
class={styles().tree.actionButton}
328303
title="Copy object to clipboard"
329-
aria-label={`${
330-
copyState() === 'NoCopy'
331-
? 'Copy object to clipboard'
332-
: copyState() === 'SuccessCopy'
333-
? 'Object copied to clipboard'
334-
: 'Error copying object to clipboard'
335-
}`}
304+
aria-label={`${copyState() === 'NoCopy'
305+
? 'Copy object to clipboard'
306+
: copyState() === 'SuccessCopy'
307+
? 'Object copied to clipboard'
308+
: 'Error copying object to clipboard'
309+
}`}
336310
onClick={
337311
copyState() === 'NoCopy'
338312
? () => {
339-
navigator.clipboard
340-
.writeText(JSON.stringify(props.value, null, 2))
341-
.then(
342-
() => {
343-
setCopyState('SuccessCopy')
344-
setTimeout(() => {
345-
setCopyState('NoCopy')
346-
}, 1500)
347-
},
348-
(err) => {
349-
console.error('Failed to copy: ', err)
350-
setCopyState('ErrorCopy')
351-
setTimeout(() => {
352-
setCopyState('NoCopy')
353-
}, 1500)
354-
},
355-
)
356-
}
313+
navigator.clipboard
314+
.writeText(JSON.stringify(props.value, null, 2))
315+
.then(
316+
() => {
317+
setCopyState('SuccessCopy')
318+
setTimeout(() => {
319+
setCopyState('NoCopy')
320+
}, 1500)
321+
},
322+
(err) => {
323+
console.error('Failed to copy: ', err)
324+
setCopyState('ErrorCopy')
325+
setTimeout(() => {
326+
setCopyState('NoCopy')
327+
}, 1500)
328+
},
329+
)
330+
}
357331
: undefined
358332
}
359333
>
@@ -383,7 +357,7 @@ const Expander = (props: { expanded: boolean; onClick: () => void }) => {
383357
transform: rotate(${props.expanded ? 90 : 0}deg);
384358
`,
385359
props.expanded &&
386-
css`
360+
css`
387361
& svg {
388362
top: -1px;
389363
}

0 commit comments

Comments
 (0)