react-component-instance 0.0.9 → 0.0.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/README.md +52 -6
- package/package.json +4 -8
- package/src/index.mjs +101 -40
- package/src/{common → utils}/index.mjs +19 -1
- package/src/container/index.mjs +0 -62
package/README.md
CHANGED
|
@@ -3,24 +3,68 @@
|
|
|
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
15
|
import {
|
|
15
16
|
render
|
|
16
17
|
} from '@testing-library/react'
|
|
17
18
|
|
|
18
|
-
import
|
|
19
|
+
import {
|
|
20
|
+
getInstance
|
|
21
|
+
} from 'react-component-instance'
|
|
19
22
|
|
|
20
23
|
describe('`getInstance`', () => {
|
|
21
24
|
class Component extends React.Component {
|
|
22
25
|
render () {
|
|
23
|
-
return
|
|
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
|
|
48
|
+
import {
|
|
49
|
+
render
|
|
50
|
+
} from '@testing-library/react'
|
|
51
|
+
|
|
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
|
+
)
|
|
24
68
|
}
|
|
25
69
|
}
|
|
26
70
|
|
|
@@ -31,7 +75,9 @@ describe('`getInstance`', () => {
|
|
|
31
75
|
<Component />
|
|
32
76
|
)
|
|
33
77
|
|
|
34
|
-
|
|
78
|
+
const child = container.querySelector('.child')
|
|
79
|
+
|
|
80
|
+
expect(findInstanceFor(child, Component))
|
|
35
81
|
.toBeInstanceOf(Component)
|
|
36
82
|
})
|
|
37
83
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-component-instance",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "Get a React class component instance from its DOM Element",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@babel/preset-env": "^7.26.9",
|
|
37
37
|
"@babel/preset-react": "^7.26.3",
|
|
38
38
|
"@sequencemedia/eslint-config-standard": "^0.2.43",
|
|
39
|
-
"@sequencemedia/eslint-config-typescript": "^0.1.
|
|
39
|
+
"@sequencemedia/eslint-config-typescript": "^0.1.63",
|
|
40
40
|
"@testing-library/jest-dom": "^6.6.3",
|
|
41
41
|
"@testing-library/react": "^16.2.0",
|
|
42
42
|
"@types/debug": "^4.1.12",
|
|
@@ -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,52 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {import('@testing-library/react').RenderResult} RenderType
|
|
3
|
+
* @typedef {ReactComponentInstanceTypes.FiberRootNode} FiberRootNode
|
|
3
4
|
* @typedef {ReactComponentInstanceTypes.FiberNode} FiberNode
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
import {
|
|
8
|
+
getContainerFiberFrom,
|
|
7
9
|
getFiberFrom,
|
|
8
10
|
getParentFiberFrom,
|
|
9
11
|
getChildFiberFrom,
|
|
10
12
|
getComponentInstance,
|
|
13
|
+
getContainerInstance,
|
|
11
14
|
isComponentType,
|
|
12
15
|
traverseFiberParents
|
|
13
|
-
} from '
|
|
16
|
+
} from './utils/index.mjs'
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
|
-
* @param {Element | null | undefined}
|
|
17
|
-
* @
|
|
18
|
-
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
19
|
+
* @param {Element | null | undefined} containerElement
|
|
20
|
+
* @returns {FiberRootNode | null | undefined}
|
|
19
21
|
*/
|
|
20
|
-
export function
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (isComponentType(Component, fiber)) {
|
|
26
|
-
return (
|
|
27
|
-
getComponentInstance(fiber)
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
for (const parentFiber of traverseFiberParents(fiber)) {
|
|
32
|
-
if (parentFiber) {
|
|
33
|
-
if (isComponentType(Component, parentFiber)) {
|
|
34
|
-
return (
|
|
35
|
-
getComponentInstance(parentFiber)
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
throw new Error('Component instance is not found')
|
|
22
|
+
export function getContainerFiberNodeFrom (containerElement) {
|
|
23
|
+
if (containerElement instanceof HTMLElement) {
|
|
24
|
+
return (
|
|
25
|
+
getContainerFiberFrom(containerElement)
|
|
26
|
+
)
|
|
43
27
|
}
|
|
44
28
|
|
|
45
|
-
throw new Error('
|
|
29
|
+
throw new Error('Container is not an Element')
|
|
46
30
|
}
|
|
47
31
|
|
|
48
32
|
/**
|
|
49
|
-
* @param {Element | null
|
|
33
|
+
* @param {Element | null} [element]
|
|
50
34
|
* @returns {FiberNode | null | undefined}
|
|
51
35
|
*/
|
|
52
36
|
export function getFiberNodeFrom (element) {
|
|
@@ -60,7 +44,7 @@ export function getFiberNodeFrom (element) {
|
|
|
60
44
|
}
|
|
61
45
|
|
|
62
46
|
/**
|
|
63
|
-
* @param {Element | null
|
|
47
|
+
* @param {Element | null} [element]
|
|
64
48
|
* @returns {FiberNode | null | undefined}
|
|
65
49
|
*/
|
|
66
50
|
export function getParentFiberNodeFrom (element) {
|
|
@@ -74,7 +58,7 @@ export function getParentFiberNodeFrom (element) {
|
|
|
74
58
|
}
|
|
75
59
|
|
|
76
60
|
/**
|
|
77
|
-
* @param {Element | null
|
|
61
|
+
* @param {Element | null} [element]
|
|
78
62
|
* @returns {FiberNode | null | undefined}
|
|
79
63
|
*/
|
|
80
64
|
export function getChildFiberNodeFrom (element) {
|
|
@@ -88,33 +72,110 @@ export function getChildFiberNodeFrom (element) {
|
|
|
88
72
|
}
|
|
89
73
|
|
|
90
74
|
/**
|
|
91
|
-
* @param {RenderType}
|
|
75
|
+
* @param {RenderType} render
|
|
92
76
|
* @returns {Element | null}
|
|
93
77
|
*/
|
|
94
|
-
export function
|
|
78
|
+
export function getComponentElementFromRender ({
|
|
95
79
|
container: {
|
|
96
|
-
firstElementChild:
|
|
80
|
+
firstElementChild: componentElement
|
|
97
81
|
}
|
|
98
82
|
}) {
|
|
99
|
-
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
|
|
100
130
|
}
|
|
101
131
|
|
|
102
132
|
/**
|
|
103
133
|
* @param {Element | null | undefined} element
|
|
134
|
+
* @param {(() => React.JSX.Element) | typeof React.Component} Component
|
|
104
135
|
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
105
136
|
*/
|
|
106
|
-
export
|
|
137
|
+
export function findInstanceFor (element, Component) {
|
|
107
138
|
if (element instanceof HTMLElement) {
|
|
108
|
-
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)
|
|
109
172
|
|
|
110
173
|
if (parentFiber) {
|
|
111
174
|
return (
|
|
112
175
|
getComponentInstance(parentFiber)
|
|
113
176
|
)
|
|
114
177
|
}
|
|
115
|
-
|
|
116
|
-
throw new Error('Component instance is not found')
|
|
117
178
|
}
|
|
118
179
|
|
|
119
|
-
|
|
180
|
+
return null
|
|
120
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,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {import('@testing-library/react').RenderResult} RenderType
|
|
3
|
-
* @typedef {ReactComponentInstanceTypes.FiberRootNode} FiberRootNode
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
getContainerFiberFrom
|
|
8
|
-
} from '#react-component-instance/common'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @param {Element | null | undefined} container
|
|
12
|
-
* @returns {FiberRootNode | null | undefined}
|
|
13
|
-
*/
|
|
14
|
-
export function getContainerFiberNodeFrom (container) {
|
|
15
|
-
if (container instanceof HTMLElement) {
|
|
16
|
-
return (
|
|
17
|
-
getContainerFiberFrom(container)
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
throw new Error('Container is not an Element')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @param {RenderType} component
|
|
26
|
-
* @returns {Element | null}
|
|
27
|
-
*/
|
|
28
|
-
export function getComponentElement ({
|
|
29
|
-
container: {
|
|
30
|
-
firstElementChild: element
|
|
31
|
-
}
|
|
32
|
-
}) {
|
|
33
|
-
return element
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @param {Element | null | undefined} container
|
|
38
|
-
* @returns {React.Component<any, any, any> | HTMLElement | Text | null}
|
|
39
|
-
*/
|
|
40
|
-
export default function getComponentInstanceFrom (container) {
|
|
41
|
-
if (container instanceof HTMLElement) {
|
|
42
|
-
const fiberNode = getContainerFiberFrom(container)
|
|
43
|
-
|
|
44
|
-
if (fiberNode) {
|
|
45
|
-
const {
|
|
46
|
-
stateNode: {
|
|
47
|
-
current: {
|
|
48
|
-
child: {
|
|
49
|
-
stateNode
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
} = fiberNode
|
|
54
|
-
|
|
55
|
-
return stateNode
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
throw new Error('Component instance is not found')
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
throw new Error('Container is not an Element')
|
|
62
|
-
}
|