react-component-instance 0.0.8 → 0.0.10
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/README.md +67 -10
- package/package.json +3 -7
- package/src/index.mjs +102 -40
- package/src/{common → utils}/index.mjs +19 -1
- package/src/container/index.mjs +0 -61
- package/tsconfig.json +0 -14
package/README.md
CHANGED
|
@@ -3,25 +3,82 @@
|
|
|
3
3
|
Get a React class component instance from its `DOM` element
|
|
4
4
|
|
|
5
5
|
```javascript
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
getInstance,
|
|
8
|
+
findInstanceFor
|
|
9
|
+
} from 'react-component-instance'
|
|
7
10
|
```
|
|
8
11
|
|
|
9
12
|
## With `@testing-library/react`
|
|
10
13
|
|
|
11
|
-
**Note** that for use with _Testing Library_ import from `react-component-instance/container`
|
|
12
|
-
|
|
13
14
|
```javascript
|
|
14
|
-
import
|
|
15
|
+
import {
|
|
16
|
+
render
|
|
17
|
+
} from '@testing-library/react'
|
|
15
18
|
|
|
19
|
+
import {
|
|
20
|
+
getInstance
|
|
21
|
+
} from 'react-component-instance'
|
|
22
|
+
|
|
23
|
+
describe('`getInstance`', () => {
|
|
24
|
+
class Component extends React.Component {
|
|
25
|
+
render () {
|
|
26
|
+
return (
|
|
27
|
+
<div className='grand-parent'>
|
|
28
|
+
<div className='parent'>
|
|
29
|
+
<div className='child'>
|
|
30
|
+
TEXT
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
it('gets the instance', () => {
|
|
39
|
+
expect(getInstance(render(
|
|
40
|
+
<Component />
|
|
41
|
+
)))
|
|
42
|
+
.toBeInstanceOf(Component)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
16
48
|
import {
|
|
17
49
|
render
|
|
18
50
|
} from '@testing-library/react'
|
|
19
51
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
)
|
|
52
|
+
import {
|
|
53
|
+
findInstanceFor
|
|
54
|
+
} from 'react-component-instance'
|
|
55
|
+
|
|
56
|
+
describe('`findInstanceFor`', () => {
|
|
57
|
+
class Component extends React.Component {
|
|
58
|
+
render () {
|
|
59
|
+
return (
|
|
60
|
+
<div className='grand-parent'>
|
|
61
|
+
<div className='parent'>
|
|
62
|
+
<div className='child'>
|
|
63
|
+
TEXT
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
it('gets the instance', () => {
|
|
72
|
+
const {
|
|
73
|
+
container
|
|
74
|
+
} = render(
|
|
75
|
+
<Component />
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const child = container.querySelector('.child')
|
|
25
79
|
|
|
26
|
-
|
|
80
|
+
expect(findInstanceFor(child, Component))
|
|
81
|
+
.toBeInstanceOf(Component)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
27
84
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-component-instance",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Get a React class component instance from its DOM Element",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -52,13 +52,9 @@
|
|
|
52
52
|
"react": "^19.0.0"
|
|
53
53
|
},
|
|
54
54
|
"imports": {
|
|
55
|
-
"#react-component-instance": "./src/index.mjs"
|
|
56
|
-
"#react-component-instance/common": "./src/common/index.mjs",
|
|
57
|
-
"#react-component-instance/container": "./src/container/index.mjs"
|
|
55
|
+
"#react-component-instance": "./src/index.mjs"
|
|
58
56
|
},
|
|
59
57
|
"exports": {
|
|
60
|
-
".": "./src/index.mjs"
|
|
61
|
-
"./common": "./src/common/index.mjs",
|
|
62
|
-
"./container": "./src/container/index.mjs"
|
|
58
|
+
".": "./src/index.mjs"
|
|
63
59
|
}
|
|
64
60
|
}
|
package/src/index.mjs
CHANGED
|
@@ -1,51 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @typedef {import('@testing-library/react').RenderResult} RenderType
|
|
3
|
+
* @typedef {ReactComponentInstanceTypes.FiberRootNode} FiberRootNode
|
|
2
4
|
* @typedef {ReactComponentInstanceTypes.FiberNode} FiberNode
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import {
|
|
8
|
+
getContainerFiberFrom,
|
|
6
9
|
getFiberFrom,
|
|
7
10
|
getParentFiberFrom,
|
|
8
11
|
getChildFiberFrom,
|
|
9
12
|
getComponentInstance,
|
|
13
|
+
getContainerInstance,
|
|
10
14
|
isComponentType,
|
|
11
15
|
traverseFiberParents
|
|
12
|
-
} from '
|
|
16
|
+
} from './utils/index.mjs'
|
|
13
17
|
|
|
14
18
|
/**
|
|
15
|
-
* @param {Element | null | undefined}
|
|
16
|
-
* @
|
|
17
|
-
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
19
|
+
* @param {Element | null | undefined} containerElement
|
|
20
|
+
* @returns {FiberRootNode | null | undefined}
|
|
18
21
|
*/
|
|
19
|
-
export function
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (isComponentType(Component, fiber)) {
|
|
25
|
-
return (
|
|
26
|
-
getComponentInstance(fiber)
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
for (const parentFiber of traverseFiberParents(fiber)) {
|
|
31
|
-
if (parentFiber) {
|
|
32
|
-
if (isComponentType(Component, parentFiber)) {
|
|
33
|
-
return (
|
|
34
|
-
getComponentInstance(parentFiber)
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
throw new Error('Component instance is not found')
|
|
22
|
+
export function getContainerFiberNodeFrom (containerElement) {
|
|
23
|
+
if (containerElement instanceof HTMLElement) {
|
|
24
|
+
return (
|
|
25
|
+
getContainerFiberFrom(containerElement)
|
|
26
|
+
)
|
|
42
27
|
}
|
|
43
28
|
|
|
44
|
-
throw new Error('
|
|
29
|
+
throw new Error('Container is not an Element')
|
|
45
30
|
}
|
|
46
31
|
|
|
47
32
|
/**
|
|
48
|
-
* @param {Element | null
|
|
33
|
+
* @param {Element | null} [element]
|
|
49
34
|
* @returns {FiberNode | null | undefined}
|
|
50
35
|
*/
|
|
51
36
|
export function getFiberNodeFrom (element) {
|
|
@@ -59,7 +44,7 @@ export function getFiberNodeFrom (element) {
|
|
|
59
44
|
}
|
|
60
45
|
|
|
61
46
|
/**
|
|
62
|
-
* @param {Element | null
|
|
47
|
+
* @param {Element | null} [element]
|
|
63
48
|
* @returns {FiberNode | null | undefined}
|
|
64
49
|
*/
|
|
65
50
|
export function getParentFiberNodeFrom (element) {
|
|
@@ -73,7 +58,7 @@ export function getParentFiberNodeFrom (element) {
|
|
|
73
58
|
}
|
|
74
59
|
|
|
75
60
|
/**
|
|
76
|
-
* @param {Element | null
|
|
61
|
+
* @param {Element | null} [element]
|
|
77
62
|
* @returns {FiberNode | null | undefined}
|
|
78
63
|
*/
|
|
79
64
|
export function getChildFiberNodeFrom (element) {
|
|
@@ -87,33 +72,110 @@ export function getChildFiberNodeFrom (element) {
|
|
|
87
72
|
}
|
|
88
73
|
|
|
89
74
|
/**
|
|
90
|
-
* @param {
|
|
75
|
+
* @param {RenderType} render
|
|
91
76
|
* @returns {Element | null}
|
|
92
77
|
*/
|
|
93
|
-
export function
|
|
78
|
+
export function getComponentElementFromRender ({
|
|
94
79
|
container: {
|
|
95
|
-
firstElementChild:
|
|
80
|
+
firstElementChild: componentElement
|
|
96
81
|
}
|
|
97
82
|
}) {
|
|
98
|
-
return
|
|
83
|
+
return componentElement
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {RenderType} render
|
|
88
|
+
* @returns {Element | null}
|
|
89
|
+
*/
|
|
90
|
+
export function getContainerElementFromRender ({
|
|
91
|
+
container: containerElement
|
|
92
|
+
}) {
|
|
93
|
+
return containerElement
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @param {Element | null} [containerElement]
|
|
98
|
+
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
99
|
+
*/
|
|
100
|
+
export function getInstanceFromContainerElement (containerElement) {
|
|
101
|
+
if (containerElement instanceof HTMLElement) {
|
|
102
|
+
const containerFiber = getContainerFiberFrom(containerElement)
|
|
103
|
+
|
|
104
|
+
if (containerFiber) {
|
|
105
|
+
return (
|
|
106
|
+
getContainerInstance(containerFiber)
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return null
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {Element | null} [componentElement]
|
|
116
|
+
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
117
|
+
*/
|
|
118
|
+
export function getInstanceFromComponentElement (componentElement) {
|
|
119
|
+
if (componentElement instanceof HTMLElement) {
|
|
120
|
+
const parentFiber = getParentFiberFrom(componentElement)
|
|
121
|
+
|
|
122
|
+
if (parentFiber) {
|
|
123
|
+
return (
|
|
124
|
+
getComponentInstance(parentFiber)
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null
|
|
99
130
|
}
|
|
100
131
|
|
|
101
132
|
/**
|
|
102
133
|
* @param {Element | null | undefined} element
|
|
134
|
+
* @param {(() => React.JSX.Element) | typeof React.Component} Component
|
|
103
135
|
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
104
136
|
*/
|
|
105
|
-
export
|
|
137
|
+
export function findInstanceFor (element, Component) {
|
|
106
138
|
if (element instanceof HTMLElement) {
|
|
107
|
-
const
|
|
139
|
+
const fiber = getFiberFrom(element)
|
|
140
|
+
|
|
141
|
+
if (fiber) {
|
|
142
|
+
if (isComponentType(Component, fiber)) {
|
|
143
|
+
return (
|
|
144
|
+
getComponentInstance(fiber)
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
for (const parentFiber of traverseFiberParents(fiber)) {
|
|
149
|
+
if (parentFiber) {
|
|
150
|
+
if (isComponentType(Component, parentFiber)) {
|
|
151
|
+
return (
|
|
152
|
+
getComponentInstance(parentFiber)
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return null
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @param {RenderType} render
|
|
165
|
+
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
166
|
+
*/
|
|
167
|
+
export function getInstance (render) {
|
|
168
|
+
const componentElement = getComponentElementFromRender(render)
|
|
169
|
+
|
|
170
|
+
if (componentElement instanceof HTMLElement) {
|
|
171
|
+
const parentFiber = getParentFiberFrom(componentElement)
|
|
108
172
|
|
|
109
173
|
if (parentFiber) {
|
|
110
174
|
return (
|
|
111
175
|
getComponentInstance(parentFiber)
|
|
112
176
|
)
|
|
113
177
|
}
|
|
114
|
-
|
|
115
|
-
throw new Error('Component instance is not found')
|
|
116
178
|
}
|
|
117
179
|
|
|
118
|
-
|
|
180
|
+
return null
|
|
119
181
|
}
|
|
@@ -156,7 +156,25 @@ export function getChildFiber ({ child: childFiber }) {
|
|
|
156
156
|
* @param {FiberNode} fiber
|
|
157
157
|
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
158
158
|
*/
|
|
159
|
-
export function getComponentInstance ({
|
|
159
|
+
export function getComponentInstance ({
|
|
160
|
+
stateNode: instance = null
|
|
161
|
+
}) {
|
|
162
|
+
return instance
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {FiberRootNode} fiber
|
|
167
|
+
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
168
|
+
*/
|
|
169
|
+
export function getContainerInstance ({
|
|
170
|
+
stateNode: {
|
|
171
|
+
current: {
|
|
172
|
+
child: {
|
|
173
|
+
stateNode: instance = null
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}) {
|
|
160
178
|
return instance
|
|
161
179
|
}
|
|
162
180
|
|
package/src/container/index.mjs
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {ReactComponentInstanceTypes.FiberRootNode} FiberRootNode
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
getContainerFiberFrom
|
|
7
|
-
} from '#react-component-instance/common'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @param {Element | null | undefined} container
|
|
11
|
-
* @returns {FiberRootNode | null | undefined}
|
|
12
|
-
*/
|
|
13
|
-
export function getContainerFiberNodeFrom (container) {
|
|
14
|
-
if (container instanceof HTMLElement) {
|
|
15
|
-
return (
|
|
16
|
-
getContainerFiberFrom(container)
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
throw new Error('Container is not an Element')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {{ container: { firstElementChild: Element | null } }} component
|
|
25
|
-
* @returns {Element | null}
|
|
26
|
-
*/
|
|
27
|
-
export function getComponentElement ({
|
|
28
|
-
container: {
|
|
29
|
-
firstElementChild: element
|
|
30
|
-
}
|
|
31
|
-
}) {
|
|
32
|
-
return element
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {Element | null | undefined} container
|
|
37
|
-
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
38
|
-
*/
|
|
39
|
-
export default function getComponentInstanceFrom (container) {
|
|
40
|
-
if (container instanceof HTMLElement) {
|
|
41
|
-
const fiberNode = getContainerFiberFrom(container)
|
|
42
|
-
|
|
43
|
-
if (fiberNode) {
|
|
44
|
-
const {
|
|
45
|
-
stateNode: {
|
|
46
|
-
current: {
|
|
47
|
-
child: {
|
|
48
|
-
stateNode
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
} = fiberNode
|
|
53
|
-
|
|
54
|
-
return stateNode
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
throw new Error('Component instance is not found')
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
throw new Error('Container is not an Element')
|
|
61
|
-
}
|