atom.io 0.33.9 → 0.33.11
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/dist/internal/index.d.ts +2 -2
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +35 -8
- package/dist/internal/index.js.map +1 -1
- package/dist/react-devtools/index.css +99 -24
- package/dist/react-devtools/index.css.map +1 -1
- package/dist/react-devtools/index.d.ts +1 -1
- package/dist/react-devtools/index.d.ts.map +1 -1
- package/dist/react-devtools/index.js +217 -188
- package/dist/react-devtools/index.js.map +1 -1
- package/package.json +12 -12
- package/src/internal/caching.ts +30 -4
- package/src/internal/operation.ts +3 -3
- package/src/internal/set-state/evict-downstream.ts +21 -2
- package/src/react-devtools/devtools.css +99 -24
- package/src/react-devtools/json-editor/editors-by-type/array-editor.tsx +47 -19
- package/src/react-devtools/json-editor/editors-by-type/object-editor.tsx +40 -43
- package/src/react-devtools/json-editor/editors-by-type/primitive-editors.tsx +5 -0
- package/src/react-devtools/json-editor/editors-by-type/utilities/object-properties.ts +30 -8
- package/src/react-devtools/json-editor/index.ts +0 -25
- package/src/react-devtools/json-editor/json-editor-internal.tsx +9 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReadableToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from "./store"
|
|
4
4
|
import { isChildStore } from "./transaction/is-root-store"
|
|
@@ -12,12 +12,12 @@ export type OperationProgress =
|
|
|
12
12
|
done: Set<string>
|
|
13
13
|
prev: Map<string, any>
|
|
14
14
|
time: number
|
|
15
|
-
token:
|
|
15
|
+
token: ReadableToken<any>
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export const openOperation = (
|
|
19
19
|
store: Store,
|
|
20
|
-
token:
|
|
20
|
+
token: ReadableToken<any>,
|
|
21
21
|
): number | undefined => {
|
|
22
22
|
if (store.operation.open) {
|
|
23
23
|
const rejectionTime = performance.now()
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Atom } from ".."
|
|
1
|
+
import type { Atom, Selector } from ".."
|
|
2
2
|
import { evictCachedValue } from "../caching"
|
|
3
3
|
import { newest } from "../lineage"
|
|
4
4
|
import { isDone, markDone } from "../operation"
|
|
5
5
|
import type { Store } from "../store"
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export function evictDownStream(store: Store, atom: Atom<any>): void {
|
|
8
8
|
const target = newest(store)
|
|
9
9
|
const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key)
|
|
10
10
|
target.logger.info(
|
|
@@ -34,3 +34,22 @@ export const evictDownStream = <T>(store: Store, atom: Atom<T>): void => {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
export function evictDownStreamFromSelector(
|
|
39
|
+
store: Store,
|
|
40
|
+
selector: Selector<any>,
|
|
41
|
+
): void {
|
|
42
|
+
const target = newest(store)
|
|
43
|
+
const relationEntries = target.selectorGraph
|
|
44
|
+
.getRelationEntries({
|
|
45
|
+
upstreamSelectorKey: selector.key,
|
|
46
|
+
})
|
|
47
|
+
.filter(([_, { source }]) => source === selector.key)
|
|
48
|
+
for (const [downstreamSelectorKey] of relationEntries) {
|
|
49
|
+
if (isDone(target, downstreamSelectorKey)) {
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
evictCachedValue(downstreamSelectorKey, target)
|
|
53
|
+
markDone(target, downstreamSelectorKey)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
main[data-css="atom_io_devtools"] {
|
|
2
2
|
--fg-color: #ccc;
|
|
3
3
|
--fg-light: #aaa;
|
|
4
|
+
--fg-soft: #777;
|
|
4
5
|
--fg-faint: #555;
|
|
6
|
+
--fg-hint: #333;
|
|
7
|
+
--fg-max: #fff;
|
|
5
8
|
--bg-color: #111;
|
|
6
9
|
--bg-accent: #00f;
|
|
10
|
+
--bg-max: #000;
|
|
7
11
|
--bg-tint1: #222;
|
|
12
|
+
--bg-tint2: #333;
|
|
8
13
|
--fg-border: 1px solid var(--fg-color);
|
|
14
|
+
--fg-border-soft: 1px solid var(--fg-soft);
|
|
9
15
|
@media (prefers-color-scheme: light) {
|
|
10
16
|
--fg-color: #444;
|
|
11
17
|
--fg-light: #777;
|
|
18
|
+
--fg-soft: #888;
|
|
12
19
|
--fg-faint: #999;
|
|
20
|
+
--fg-hint: #ccc;
|
|
21
|
+
--fg-max: #000;
|
|
13
22
|
--bg-color: #ddd;
|
|
14
23
|
--bg-accent: #0ff;
|
|
24
|
+
--bg-max: #fff;
|
|
15
25
|
--bg-tint1: #e3e3e3;
|
|
26
|
+
--bg-tint2: #f3f3f3;
|
|
16
27
|
}
|
|
17
28
|
& {
|
|
18
29
|
pointer-events: all;
|
|
@@ -42,14 +53,20 @@ main[data-css="atom_io_devtools"] {
|
|
|
42
53
|
display: flex;
|
|
43
54
|
justify-content: space-between;
|
|
44
55
|
h1 {
|
|
45
|
-
margin:
|
|
56
|
+
margin: 2px 4px;
|
|
46
57
|
font-size: 24px;
|
|
47
58
|
font-family: charter, serif;
|
|
48
59
|
}
|
|
49
60
|
nav {
|
|
61
|
+
position: relative;
|
|
50
62
|
display: flex;
|
|
51
63
|
flex-flow: row nowrap;
|
|
64
|
+
margin-top: 4px;
|
|
65
|
+
overflow-x: scroll;
|
|
66
|
+
overflow-y: visible;
|
|
67
|
+
height: 24px;
|
|
52
68
|
button {
|
|
69
|
+
height: 24px;
|
|
53
70
|
cursor: pointer;
|
|
54
71
|
background: none;
|
|
55
72
|
border: none;
|
|
@@ -58,10 +75,9 @@ main[data-css="atom_io_devtools"] {
|
|
|
58
75
|
z-index: 1000;
|
|
59
76
|
&:disabled {
|
|
60
77
|
cursor: default;
|
|
61
|
-
background-color: var(--
|
|
62
|
-
color: var(--
|
|
78
|
+
background-color: var(--fg-color);
|
|
79
|
+
color: var(--bg-color);
|
|
63
80
|
border: var(--fg-border);
|
|
64
|
-
border-bottom: none;
|
|
65
81
|
}
|
|
66
82
|
}
|
|
67
83
|
}
|
|
@@ -69,6 +85,10 @@ main[data-css="atom_io_devtools"] {
|
|
|
69
85
|
> main {
|
|
70
86
|
background: var(--bg-tint1);
|
|
71
87
|
}
|
|
88
|
+
> main::before {
|
|
89
|
+
background-color: black;
|
|
90
|
+
height: 10px;
|
|
91
|
+
}
|
|
72
92
|
main {
|
|
73
93
|
overflow-y: scroll;
|
|
74
94
|
flex-grow: 1;
|
|
@@ -86,7 +106,7 @@ main[data-css="atom_io_devtools"] {
|
|
|
86
106
|
}
|
|
87
107
|
.node > .node {
|
|
88
108
|
margin: 0px 2px 2px 18px;
|
|
89
|
-
border-left: var(--fg-border);
|
|
109
|
+
border-left: var(--fg-border-soft);
|
|
90
110
|
&:last-of-type {
|
|
91
111
|
margin-bottom: 6px;
|
|
92
112
|
}
|
|
@@ -107,6 +127,8 @@ main[data-css="atom_io_devtools"] {
|
|
|
107
127
|
z-index: 999;
|
|
108
128
|
top: 0;
|
|
109
129
|
height: 22px;
|
|
130
|
+
background: var(--bg-tint2);
|
|
131
|
+
border-bottom: var(--fg-border-soft);
|
|
110
132
|
button.carat {
|
|
111
133
|
cursor: pointer;
|
|
112
134
|
background: none;
|
|
@@ -118,7 +140,10 @@ main[data-css="atom_io_devtools"] {
|
|
|
118
140
|
}
|
|
119
141
|
&:disabled {
|
|
120
142
|
cursor: default;
|
|
121
|
-
|
|
143
|
+
}
|
|
144
|
+
&:focus-within {
|
|
145
|
+
outline: 2px solid var(--fg-max);
|
|
146
|
+
background: var(--bg-max);
|
|
122
147
|
}
|
|
123
148
|
}
|
|
124
149
|
> main {
|
|
@@ -126,6 +151,7 @@ main[data-css="atom_io_devtools"] {
|
|
|
126
151
|
flex-flow: row;
|
|
127
152
|
cursor: help;
|
|
128
153
|
align-items: center;
|
|
154
|
+
flex-shrink: 0;
|
|
129
155
|
* {
|
|
130
156
|
height: 100%;
|
|
131
157
|
display: flex;
|
|
@@ -150,21 +176,24 @@ main[data-css="atom_io_devtools"] {
|
|
|
150
176
|
> .json_editor,
|
|
151
177
|
> .json_viewer {
|
|
152
178
|
display: flex;
|
|
179
|
+
flex-shrink: 1;
|
|
180
|
+
z-index: -1;
|
|
181
|
+
overflow-x: scroll;
|
|
153
182
|
align-items: center;
|
|
154
|
-
border-left:
|
|
155
|
-
|
|
156
|
-
|
|
183
|
+
border-left: var(--fg-border-soft);
|
|
184
|
+
white-space: pre;
|
|
185
|
+
background: var(--bg-tint2);
|
|
186
|
+
&:focus-within {
|
|
187
|
+
background-color: var(--bg-max);
|
|
188
|
+
outline: 2px solid var(--fg-max);
|
|
189
|
+
}
|
|
190
|
+
&.nu * {
|
|
157
191
|
display: flex;
|
|
158
192
|
height: 100%;
|
|
159
193
|
}
|
|
160
194
|
> span {
|
|
161
195
|
padding: 0px 5px;
|
|
162
|
-
border-left: var(--fg-color);
|
|
163
196
|
z-index: 0;
|
|
164
|
-
&:focus-within {
|
|
165
|
-
outline: 4px solid var(--fg-color);
|
|
166
|
-
background: var(--bg-accent);
|
|
167
|
-
}
|
|
168
197
|
}
|
|
169
198
|
input {
|
|
170
199
|
outline: none;
|
|
@@ -288,12 +317,34 @@ main[data-css="atom_io_devtools"] {
|
|
|
288
317
|
border: none;
|
|
289
318
|
}
|
|
290
319
|
}
|
|
320
|
+
input,
|
|
321
|
+
button,
|
|
322
|
+
select {
|
|
323
|
+
&:focus-within {
|
|
324
|
+
outline: 2px solid var(--fg-max);
|
|
325
|
+
background: var(--bg-max);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
button:disabled {
|
|
329
|
+
cursor: default;
|
|
330
|
+
> span.json_editor_icon {
|
|
331
|
+
color: var(--fg-hint);
|
|
332
|
+
}
|
|
333
|
+
&:hover {
|
|
334
|
+
background: none;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
input::selection {
|
|
338
|
+
background: var(--bg-accent);
|
|
339
|
+
}
|
|
340
|
+
|
|
291
341
|
button {
|
|
292
342
|
background: none;
|
|
293
343
|
color: #777;
|
|
294
344
|
border: none;
|
|
295
345
|
font-family: theia, monospace;
|
|
296
346
|
font-size: 14px;
|
|
347
|
+
height: 21px;
|
|
297
348
|
margin: none;
|
|
298
349
|
padding: 4px;
|
|
299
350
|
padding-bottom: 6px;
|
|
@@ -323,7 +374,10 @@ main[data-css="atom_io_devtools"] {
|
|
|
323
374
|
background-color: #f055;
|
|
324
375
|
}
|
|
325
376
|
.json_editor_key {
|
|
326
|
-
padding-right:
|
|
377
|
+
padding-right: 0px;
|
|
378
|
+
&::after {
|
|
379
|
+
content: ":";
|
|
380
|
+
}
|
|
327
381
|
input {
|
|
328
382
|
color: #999;
|
|
329
383
|
@media (prefers-color-scheme: light) {
|
|
@@ -331,16 +385,37 @@ main[data-css="atom_io_devtools"] {
|
|
|
331
385
|
}
|
|
332
386
|
}
|
|
333
387
|
}
|
|
334
|
-
.json_editor_object
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
.
|
|
341
|
-
|
|
342
|
-
|
|
388
|
+
.json_editor_object,
|
|
389
|
+
.json_editor_array {
|
|
390
|
+
border-left: var(--fg-border-soft);
|
|
391
|
+
padding-left: 12px;
|
|
392
|
+
margin-left: 8px;
|
|
393
|
+
.json_editor_properties,
|
|
394
|
+
.json_editor_elements {
|
|
395
|
+
.json_editor_property,
|
|
396
|
+
.json_editor_element {
|
|
397
|
+
border-bottom: var(--fg-border-soft);
|
|
343
398
|
margin-bottom: 2px;
|
|
399
|
+
min-height: 23px;
|
|
400
|
+
> span {
|
|
401
|
+
input {
|
|
402
|
+
min-width: 10px;
|
|
403
|
+
}
|
|
404
|
+
> * {
|
|
405
|
+
border: var(--fg-border-soft);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
&.readonly {
|
|
410
|
+
.json_editor_property,
|
|
411
|
+
.json_editor_element {
|
|
412
|
+
&:last-of-type {
|
|
413
|
+
border-bottom: none;
|
|
414
|
+
}
|
|
415
|
+
> span > * {
|
|
416
|
+
border: 1px solid transparent;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
344
419
|
}
|
|
345
420
|
}
|
|
346
421
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Json, JSON_DEFAULTS } from "atom.io/json"
|
|
2
2
|
import type { ReactElement } from "react"
|
|
3
3
|
|
|
4
4
|
import type { JsonEditorProps_INTERNAL } from "../json-editor-internal"
|
|
5
5
|
import { JsonEditor_INTERNAL } from "../json-editor-internal"
|
|
6
6
|
import { makeElementSetters } from "./utilities/array-elements"
|
|
7
|
+
import {
|
|
8
|
+
makePropertyRecasters,
|
|
9
|
+
makePropertyRemovers,
|
|
10
|
+
} from "./utilities/object-properties"
|
|
7
11
|
|
|
8
12
|
export const ArrayEditor = ({
|
|
9
13
|
path = [],
|
|
@@ -14,25 +18,49 @@ export const ArrayEditor = ({
|
|
|
14
18
|
Components,
|
|
15
19
|
testid,
|
|
16
20
|
}: JsonEditorProps_INTERNAL<Json.Tree.Array>): ReactElement => {
|
|
21
|
+
const disabled = isReadonly(path)
|
|
22
|
+
|
|
17
23
|
const setElement = makeElementSetters(data, set)
|
|
24
|
+
const removeElement = makePropertyRemovers(data, set)
|
|
25
|
+
const recastElement = makePropertyRecasters(data, set)
|
|
26
|
+
|
|
18
27
|
return (
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
<Components.ArrayWrapper>
|
|
29
|
+
<div className={`json_editor_elements${disabled ? ` readonly` : ``}`}>
|
|
30
|
+
{data.map((element, index) => {
|
|
31
|
+
const newPath = [...path, index]
|
|
32
|
+
return (
|
|
33
|
+
<JsonEditor_INTERNAL
|
|
34
|
+
key={newPath.join(``)}
|
|
35
|
+
path={newPath}
|
|
36
|
+
name={`${index}`}
|
|
37
|
+
isReadonly={isReadonly}
|
|
38
|
+
isHidden={isHidden}
|
|
39
|
+
data={element}
|
|
40
|
+
set={setElement[index]}
|
|
41
|
+
remove={removeElement[index]}
|
|
42
|
+
recast={recastElement[index]}
|
|
43
|
+
className="json_editor_element"
|
|
44
|
+
Components={Components}
|
|
45
|
+
testid={`${testid}-element-${index}`}
|
|
46
|
+
/>
|
|
47
|
+
)
|
|
48
|
+
})}
|
|
49
|
+
</div>
|
|
50
|
+
{disabled ? null : (
|
|
51
|
+
<Components.Button
|
|
52
|
+
testid={`${testid}-add-element`}
|
|
53
|
+
disabled={disabled}
|
|
54
|
+
onClick={() => {
|
|
55
|
+
set((current) => {
|
|
56
|
+
const newData = [...current, JSON_DEFAULTS.string]
|
|
57
|
+
return newData
|
|
58
|
+
})
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
+
|
|
62
|
+
</Components.Button>
|
|
63
|
+
)}
|
|
64
|
+
</Components.ArrayWrapper>
|
|
37
65
|
)
|
|
38
66
|
}
|
|
@@ -72,48 +72,36 @@ export const ObjectEditor = <T extends Json.Tree.Object>({
|
|
|
72
72
|
const makePropertyAdder = makePropertyCreationInterface(data, set)
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
disabled={disabled}
|
|
82
|
-
>
|
|
83
|
-
Sort
|
|
84
|
-
</Components.Button>
|
|
85
|
-
<Components.ObjectWrapper>
|
|
86
|
-
<div className="json_editor_properties">
|
|
87
|
-
{Object.keys(data).map((key) => {
|
|
88
|
-
const originalKey = stableKeyMap.current[key]
|
|
89
|
-
const newPath = [...path, key]
|
|
90
|
-
const originalPath = [...path, originalKey]
|
|
75
|
+
<Components.ObjectWrapper>
|
|
76
|
+
<div className={`json_editor_properties${disabled ? ` readonly` : ``}`}>
|
|
77
|
+
{Object.keys(data).map((key) => {
|
|
78
|
+
const originalKey = stableKeyMap.current[key]
|
|
79
|
+
const newPath = [...path, key]
|
|
80
|
+
const originalPath = [...path, originalKey]
|
|
91
81
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
+
|
|
114
|
-
</Components.Button>
|
|
115
|
-
) : (
|
|
82
|
+
return (
|
|
83
|
+
<JsonEditor_INTERNAL
|
|
84
|
+
key={originalPath.join(`.`)}
|
|
85
|
+
path={newPath}
|
|
86
|
+
name={key}
|
|
87
|
+
isReadonly={isReadonly}
|
|
88
|
+
isHidden={isHidden}
|
|
89
|
+
data={data[key as keyof T]}
|
|
90
|
+
set={setProperty[key as keyof T]}
|
|
91
|
+
rename={renameProperty[key as keyof T]}
|
|
92
|
+
remove={removeProperty[key as keyof T]}
|
|
93
|
+
recast={recastProperty[key as keyof T]}
|
|
94
|
+
className="json_editor_property"
|
|
95
|
+
Components={Components}
|
|
96
|
+
testid={`${testid}-property-${key}`}
|
|
97
|
+
/>
|
|
98
|
+
)
|
|
99
|
+
})}
|
|
100
|
+
</div>
|
|
101
|
+
{disabled ? null : (
|
|
102
|
+
<>
|
|
116
103
|
<Components.Button
|
|
104
|
+
disabled={disabled}
|
|
117
105
|
testid={`${testid}-add-property`}
|
|
118
106
|
onClick={() => {
|
|
119
107
|
makePropertyAdder(`new_property`, `string`)()
|
|
@@ -121,8 +109,17 @@ export const ObjectEditor = <T extends Json.Tree.Object>({
|
|
|
121
109
|
>
|
|
122
110
|
+
|
|
123
111
|
</Components.Button>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
112
|
+
<Components.Button
|
|
113
|
+
testid={`${testid}-sort-properties`}
|
|
114
|
+
onClick={() => {
|
|
115
|
+
sortProperties()
|
|
116
|
+
}}
|
|
117
|
+
disabled={disabled}
|
|
118
|
+
>
|
|
119
|
+
Sort
|
|
120
|
+
</Components.Button>
|
|
121
|
+
</>
|
|
122
|
+
)}
|
|
123
|
+
</Components.ObjectWrapper>
|
|
127
124
|
)
|
|
128
125
|
}
|
|
@@ -4,6 +4,8 @@ import { NumberInput, TextInput } from "../../elastic-input"
|
|
|
4
4
|
import type { JsonEditorProps_INTERNAL } from "../json-editor-internal"
|
|
5
5
|
|
|
6
6
|
export const BooleanEditor = ({
|
|
7
|
+
path = [],
|
|
8
|
+
isReadonly = () => false,
|
|
7
9
|
data,
|
|
8
10
|
set,
|
|
9
11
|
Components,
|
|
@@ -11,6 +13,7 @@ export const BooleanEditor = ({
|
|
|
11
13
|
}: JsonEditorProps_INTERNAL<boolean>): ReactElement => (
|
|
12
14
|
<Components.BooleanWrapper>
|
|
13
15
|
<input
|
|
16
|
+
disabled={isReadonly(path)}
|
|
14
17
|
data-testid={`${testid}-boolean-input`}
|
|
15
18
|
type="checkbox"
|
|
16
19
|
checked={data}
|
|
@@ -38,6 +41,7 @@ export const NumberEditor = ({
|
|
|
38
41
|
}: JsonEditorProps_INTERNAL<number>): ReactElement => (
|
|
39
42
|
<Components.NumberWrapper>
|
|
40
43
|
<NumberInput
|
|
44
|
+
disabled={isReadonly(path)}
|
|
41
45
|
testid={`${testid}-number-input`}
|
|
42
46
|
value={data}
|
|
43
47
|
set={
|
|
@@ -63,6 +67,7 @@ export const StringEditor = ({
|
|
|
63
67
|
return (
|
|
64
68
|
<Components.StringWrapper>
|
|
65
69
|
<TextInput
|
|
70
|
+
readOnly={isReadonly(path)}
|
|
66
71
|
testid={`${testid}-string-input`}
|
|
67
72
|
value={data}
|
|
68
73
|
set={isReadonly(path) ? undefined : set}
|
|
@@ -45,7 +45,9 @@ export const makePropertyRenamers = <T extends Json.Tree.Object>(
|
|
|
45
45
|
]),
|
|
46
46
|
)
|
|
47
47
|
|
|
48
|
-
export const makePropertyRemovers = <
|
|
48
|
+
export const makePropertyRemovers = <
|
|
49
|
+
T extends Json.Tree.Array | Json.Tree.Object,
|
|
50
|
+
>(
|
|
49
51
|
data: T,
|
|
50
52
|
set: SetterOrUpdater<T>,
|
|
51
53
|
): { [K in keyof T]: () => void } =>
|
|
@@ -54,14 +56,24 @@ export const makePropertyRemovers = <T extends Json.Tree.Object>(
|
|
|
54
56
|
key,
|
|
55
57
|
() => {
|
|
56
58
|
set(() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
let next: T
|
|
60
|
+
if (Array.isArray(data)) {
|
|
61
|
+
const copy = [...data]
|
|
62
|
+
copy.splice(key as number, 1)
|
|
63
|
+
next = copy as unknown as T
|
|
64
|
+
} else {
|
|
65
|
+
const { [key]: _, ...rest } = data
|
|
66
|
+
next = rest as T
|
|
67
|
+
}
|
|
68
|
+
return next
|
|
59
69
|
})
|
|
60
70
|
},
|
|
61
71
|
]),
|
|
62
72
|
)
|
|
63
73
|
|
|
64
|
-
export const makePropertyRecasters = <
|
|
74
|
+
export const makePropertyRecasters = <
|
|
75
|
+
T extends Json.Tree.Array | Json.Tree.Object,
|
|
76
|
+
>(
|
|
65
77
|
data: T,
|
|
66
78
|
set: SetterOrUpdater<T>,
|
|
67
79
|
): { [K in keyof T]: (newType: JsonTypeName) => void } =>
|
|
@@ -69,10 +81,20 @@ export const makePropertyRecasters = <T extends Json.Tree.Object>(
|
|
|
69
81
|
toEntries(data).map(([key, value]) => [
|
|
70
82
|
key,
|
|
71
83
|
(newType: JsonTypeName) => {
|
|
72
|
-
set(() =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
set(() => {
|
|
85
|
+
let next: T
|
|
86
|
+
if (Array.isArray(data)) {
|
|
87
|
+
const copy = [...data]
|
|
88
|
+
copy[key as number] = castToJson(value)[newType]
|
|
89
|
+
next = copy as unknown as T
|
|
90
|
+
} else {
|
|
91
|
+
next = {
|
|
92
|
+
...data,
|
|
93
|
+
[key]: castToJson(value)[newType],
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return next
|
|
97
|
+
})
|
|
76
98
|
},
|
|
77
99
|
]),
|
|
78
100
|
)
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
import type { JsonTypes } from "atom.io/json"
|
|
2
|
-
import type { FC } from "react"
|
|
3
|
-
|
|
4
|
-
import { ArrayEditor } from "./editors-by-type/array-editor"
|
|
5
|
-
import { ObjectEditor } from "./editors-by-type/object-editor"
|
|
6
|
-
import {
|
|
7
|
-
BooleanEditor,
|
|
8
|
-
NullEditor,
|
|
9
|
-
NumberEditor,
|
|
10
|
-
StringEditor,
|
|
11
|
-
} from "./editors-by-type/primitive-editors"
|
|
12
|
-
import type { JsonEditorProps_INTERNAL } from "./json-editor-internal"
|
|
13
|
-
|
|
14
1
|
export * from "./default-components"
|
|
15
2
|
export * from "./developer-interface"
|
|
16
3
|
export * from "./editors-by-type/utilities/cast-to-json"
|
|
@@ -18,15 +5,3 @@ export * from "./editors-by-type/utilities/cast-to-json"
|
|
|
18
5
|
export type SetterOrUpdater<T> = <New extends T>(
|
|
19
6
|
next: New | ((old: T) => New),
|
|
20
7
|
) => void
|
|
21
|
-
|
|
22
|
-
export const SubEditors: Record<
|
|
23
|
-
keyof JsonTypes,
|
|
24
|
-
FC<JsonEditorProps_INTERNAL<any>>
|
|
25
|
-
> = {
|
|
26
|
-
array: ArrayEditor,
|
|
27
|
-
boolean: BooleanEditor,
|
|
28
|
-
null: NullEditor,
|
|
29
|
-
number: NumberEditor,
|
|
30
|
-
object: ObjectEditor,
|
|
31
|
-
string: StringEditor,
|
|
32
|
-
}
|
|
@@ -61,20 +61,15 @@ export const JsonEditor_INTERNAL = <T,>({
|
|
|
61
61
|
testid={testid}
|
|
62
62
|
>
|
|
63
63
|
{remove ? (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}}
|
|
74
|
-
>
|
|
75
|
-
<Components.DeleteIcon />
|
|
76
|
-
</Components.Button>
|
|
77
|
-
)
|
|
64
|
+
<Components.Button
|
|
65
|
+
disabled={disabled}
|
|
66
|
+
onClick={() => {
|
|
67
|
+
remove()
|
|
68
|
+
}}
|
|
69
|
+
testid={`${testid}-delete`}
|
|
70
|
+
>
|
|
71
|
+
<Components.DeleteIcon />
|
|
72
|
+
</Components.Button>
|
|
78
73
|
) : null}
|
|
79
74
|
{HeaderDisplay && <HeaderDisplay data={data} />}
|
|
80
75
|
{rename && (
|