|
14 | 14 | keys?: string[];
|
15 | 15 | }
|
16 | 16 |
|
17 |
| - const { entries = [], keys = [] }: Props = $props(); |
| 17 | + const { entries = [], keys: parents = [] }: Props = $props(); |
18 | 18 |
|
19 |
| - let expanded = $state(false); |
| 19 | + const expanded = $state<{ [k: string]: boolean }>({}); |
20 | 20 | </script>
|
21 | 21 |
|
22 | 22 | {#if entries.length}
|
23 | 23 | <ul>
|
24 | 24 | {#each entries as { key, value, readonly = false } (key)}
|
25 |
| - {@const id = `${app.selected?.id}+${keys.join('.')}.${key}`} |
| 25 | + {@const keys = [...parents, key]} |
26 | 26 | {@const type = typeof value}
|
27 | 27 |
|
28 | 28 | <!-- svelte-ignore a11y-click-events-have-key-events -->
|
29 | 29 | <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
30 | 30 | <li
|
31 |
| - data-tooltip={errors[id] || null} |
| 31 | + data-tooltip={errors[`${app.selected?.id}+${keys.join('.')}`] || null} |
32 | 32 | style:--indent="-3px"
|
33 | 33 | style:--y-pad="0.125rem"
|
34 |
| - class:expanded |
| 34 | + class:expanded={expanded[key]} |
35 | 35 | class:expandable={value != null &&
|
36 | 36 | value === value &&
|
37 | 37 | type === 'object' &&
|
|
41 | 41 | Object.keys(value).length)}
|
42 | 42 | onclick={(event) => {
|
43 | 43 | event.stopPropagation();
|
44 |
| - expanded = !expanded; |
| 44 | + expanded[key] = !expanded[key]; |
45 | 45 | }}
|
46 | 46 | >
|
47 | 47 | <span>{key}:</span>
|
|
52 | 52 | {readonly}
|
53 | 53 | type="string"
|
54 | 54 | {value}
|
55 |
| - onchange={(updated) => inject([...keys, key], updated)} |
| 55 | + onchange={(updated) => inject(keys, updated)} |
56 | 56 | />
|
57 | 57 | {:else if value == null || value !== value}
|
58 | 58 | <Editable
|
59 | 59 | {readonly}
|
60 | 60 | type="null"
|
61 | 61 | value={value === null ? 'null' : 'undefined'}
|
62 |
| - onchange={(updated) => inject([...keys, key], updated)} |
| 62 | + onchange={(updated) => inject(keys, updated)} |
63 | 63 | />
|
64 | 64 | {:else if type === 'number' || type === 'boolean'}
|
65 | 65 | <Editable
|
66 | 66 | {readonly}
|
67 | 67 | type="number"
|
68 | 68 | {value}
|
69 |
| - onchange={(updated) => inject([...keys, key], updated)} |
| 69 | + onchange={(updated) => inject(keys, updated)} |
70 | 70 | />
|
71 | 71 | {:else if Array.isArray(value)}
|
72 | 72 | <span class="object">Array [{value.length || ''}]</span>
|
73 | 73 |
|
74 |
| - {#if value.length && expanded} |
| 74 | + {#if value.length && expanded[key]} |
75 | 75 | {@const entries = value.map((v, i) => ({ key: `${i}`, value: v, readonly }))}
|
76 | 76 |
|
77 |
| - <PropertyList {entries} keys={[...keys, key]} /> |
| 77 | + <PropertyList {entries} {keys} /> |
78 | 78 | {/if}
|
79 | 79 | {:else if type === 'object'}
|
80 | 80 | {#if value.__is === 'function'}
|
81 | 81 | <span class="function">function {value.name || ''}()</span>
|
82 |
| - {#if expanded}<pre style:width="100%">{value.source}</pre>{/if} |
| 82 | + {#if expanded[key]}<pre style:width="100%">{value.source}</pre>{/if} |
83 | 83 | {:else if value.__is === 'symbol'}
|
84 | 84 | <span class="symbol">{value.name || 'Symbol()'}</span>
|
85 | 85 | {:else if Object.keys(value).length}
|
86 | 86 | <span class="object">Object {…}</span>
|
87 | 87 |
|
88 |
| - {#if expanded} |
| 88 | + {#if expanded[key]} |
89 | 89 | {@const entries = Object.entries(value).map(([key, v]) => {
|
90 | 90 | return { key, value: v, readonly };
|
91 | 91 | })}
|
92 | 92 |
|
93 |
| - <PropertyList {entries} keys={[...keys, key]} /> |
| 93 | + <PropertyList {entries} {keys} /> |
94 | 94 | {/if}
|
95 | 95 | {:else}
|
96 | 96 | <span class="object">Object { }</span>
|
|
0 commit comments