@@ -8,9 +8,18 @@ import {
8
8
mergeRefs
9
9
} from "@editable-jsx/state"
10
10
import { toast } from "@editable-jsx/ui"
11
- import { Dispatch , SetStateAction , useEffect , useState } from "react"
12
- import { Editor } from "./Editor"
11
+ import {
12
+ createElement ,
13
+ Dispatch ,
14
+ FC ,
15
+ SetStateAction ,
16
+ useEffect ,
17
+ useState
18
+ } from "react"
19
+ import { Editable , editable } from "./editable"
20
+ import { EditableDocument , EditableRoot } from "./EditableRoot"
13
21
import { PropChange } from "./prop-types/types"
22
+ import { REF_SYMBOL } from "./REF_SYMBOL"
14
23
15
24
/**
16
25
* An editable element is a wrapper around a React element that can be edited in the editor.
@@ -32,7 +41,12 @@ import { PropChange } from "./prop-types/types"
32
41
*
33
42
* */
34
43
export class EditableElement <
35
- Ref extends { name ?: string ; visible ?: boolean } = any
44
+ Ref extends {
45
+ name ?: string
46
+ visible ?: boolean
47
+ [ k : string ] : any
48
+ [ REF_SYMBOL ] : any
49
+ } = any
36
50
> extends EventTarget {
37
51
ref ?: Ref
38
52
childIds : string [ ] = [ ]
@@ -41,7 +55,7 @@ export class EditableElement<
41
55
forwardedRef : boolean = false
42
56
dirty : any = false
43
57
properties : ControlledStore = createControlledStore ( )
44
- editor : Editor = { } as any
58
+ // editor: Editor = {} as any
45
59
index : string | undefined
46
60
refs = {
47
61
setKey : null as Dispatch < SetStateAction < number > > | null ,
@@ -53,6 +67,12 @@ export class EditableElement<
53
67
mounted : boolean = false
54
68
args = [ ] as any [ ]
55
69
70
+ /** assigned by the creator */
71
+ ownerDocument ! : EditableDocument
72
+
73
+ /** assigned by the creator */
74
+ root ! : EditableRoot
75
+
56
76
constructor (
57
77
public id : string ,
58
78
public source : JSXSource ,
@@ -63,6 +83,10 @@ export class EditableElement<
63
83
super ( )
64
84
}
65
85
86
+ getRootNode ( ) {
87
+ return this . #root
88
+ }
89
+
66
90
remount ( ) {
67
91
this . refs . setKey ?.( ( i ) => i + 1 )
68
92
}
@@ -75,19 +99,63 @@ export class EditableElement<
75
99
return this . properties . useStore ( ( s ) => s . data [ "name" ] . value as string )
76
100
}
77
101
78
- useChildren ( ) {
79
- return this . editor . useStore ( ( s ) => [
80
- ...( s . elements [ this . id ] ?. children ?? [ ] )
81
- ] )
82
- }
102
+ // useChildren() {
103
+ // return this.editor.useStore((s) => [
104
+ // ...(s.elements[this.id]?.children ?? [])
105
+ // ])
106
+ // }
83
107
84
108
useIsDirty ( ) {
85
109
return this . properties ?. useStore (
86
110
( s ) => Object . keys ( this . changes ) . length > 0
87
111
)
88
112
}
89
113
90
- appendChild ( id : string ) {
114
+ appendChild ( element : EditableElement ) {
115
+ this . childIds . push ( element . id )
116
+ }
117
+
118
+ removeChild ( element : EditableElement ) {
119
+ this . childIds = this . childIds . filter ( ( id ) => id !== element . id )
120
+ }
121
+
122
+ appendNewElement (
123
+ element : EditableElement ,
124
+ componentType : string | FC ,
125
+ props : any
126
+ ) {
127
+ console . log ( "appendNewElement" , componentType )
128
+ if ( typeof componentType === "string" ) {
129
+ console . log ( "appendNewElement" , componentType )
130
+ element . refs . setMoreChildren ?.( ( children ) => [
131
+ ...children ,
132
+ createElement ( editable [ componentType ] , {
133
+ _source : {
134
+ ...element . source ,
135
+ lineNumber : - 1 ,
136
+ elementName : componentType
137
+ } ,
138
+ key : children . length ,
139
+ ...props
140
+ } )
141
+ ] )
142
+ } else {
143
+ console . log ( "appendNewElement" , componentType )
144
+ element . refs . setMoreChildren ?.( ( children ) => [
145
+ ...children ,
146
+ createElement ( Editable , {
147
+ component : componentType ,
148
+ _source : {
149
+ ...element . source ,
150
+ lineNumber : - 1 ,
151
+ elementName :
152
+ componentType . displayName || componentType . name || undefined
153
+ } ,
154
+ key : children . length ,
155
+ ...props
156
+ } as any )
157
+ ] )
158
+ }
91
159
}
92
160
93
161
update ( source : JSXSource , props : any ) {
@@ -169,7 +237,7 @@ export class EditableElement<
169
237
170
238
setRef ( el : Ref ) {
171
239
this . ref = el
172
- this . editor . setRef ( this , el )
240
+ el [ REF_SYMBOL ] = this
173
241
this . dispatchEvent (
174
242
new CustomEvent ( "ref-changed" , {
175
243
detail : {
@@ -229,11 +297,11 @@ export class EditableElement<
229
297
}
230
298
231
299
useIsSelected ( ) {
232
- return this . editor . useState ( ( state ) => this . isSelected )
300
+ return this . ownerDocument . useState ( ( state ) => this . isSelected )
233
301
}
234
302
235
303
get isSelected ( ) {
236
- return this . editor . state . context . selectedId === this . treeId
304
+ return this . ownerDocument . state . context . selectedId === this . treeId
237
305
}
238
306
239
307
useCollapsed ( ) : [ any , any ] {
@@ -318,7 +386,7 @@ export class EditableElement<
318
386
let controls = { }
319
387
let entity = this
320
388
321
- this . editor . plugins . forEach ( ( plugin ) => {
389
+ this . ownerDocument . plugins . forEach ( ( plugin ) => {
322
390
if ( plugin . controls && plugin . applicable ( entity ) ) {
323
391
Object . assign ( controls , plugin . controls ( entity ) )
324
392
}
@@ -328,8 +396,8 @@ export class EditableElement<
328
396
}
329
397
330
398
get icon ( ) {
331
- for ( var i = this . editor . plugins . length - 1 ; i >= 0 ; i -- ) {
332
- let plugin = this . editor . plugins [ i ]
399
+ for ( var i = this . ownerDocument . plugins . length - 1 ; i >= 0 ; i -- ) {
400
+ let plugin = this . ownerDocument . plugins [ i ]
333
401
if ( plugin . icon && plugin . applicable ( this ) ) {
334
402
return plugin . icon ( this )
335
403
}
@@ -349,7 +417,7 @@ export class EditableElement<
349
417
)
350
418
351
419
try {
352
- console . log ( await this . editor . save ( diffs ) )
420
+ console . log ( await this . ownerDocument . save ( diffs ) )
353
421
this . changes = { }
354
422
this . changed = false
355
423
} catch ( e : any ) {
@@ -372,12 +440,12 @@ export class EditableElement<
372
440
373
441
get children ( ) {
374
442
return this . childIds
375
- . map ( ( id ) => this . editor . getElementById ( id ) ! )
443
+ . map ( ( id ) => this . ownerDocument . getElementById ( id ) ! )
376
444
. filter ( Boolean )
377
445
}
378
446
379
447
get parent ( ) {
380
- return this . editor . getElementById ( this . parentId ! )
448
+ return this . ownerDocument . getElementById ( this . parentId ! )
381
449
}
382
450
383
451
getObjectByPath < T > ( path : string [ ] ) : T {
@@ -395,7 +463,7 @@ export class EditableElement<
395
463
if ( path . length > 1 ) {
396
464
for ( let i = 0 ; i < path . length - 1 ; i ++ ) {
397
465
el = el ?. [ path [ i ] ]
398
- let edit = this . editor . findEditableElement ( el )
466
+ let edit = this . getRootNode ( ) . findEditableElement ( el )
399
467
if ( edit ) {
400
468
editable = edit
401
469
remainingPath = path . slice ( i + 1 )
0 commit comments