@@ -15,18 +15,25 @@ import ButtonIcon from '../ButtonIcon';
15
15
import ViewSourceContext from '../Components/ViewSourceContext' ;
16
16
import { useContext } from 'react' ;
17
17
import { TimelineContext } from 'react-devtools-timeline/src/TimelineContext' ;
18
+ import {
19
+ formatTimestamp ,
20
+ getSchedulingEventLabel ,
21
+ } from 'react-devtools-timeline/src/utils/formatting' ;
18
22
import { stackToComponentSources } from 'react-devtools-shared/src/devtools/utils' ;
23
+ import { copy } from 'clipboard-js' ;
19
24
20
25
import styles from './SidebarEventInfo.css' ;
21
26
22
27
export type Props = { || } ;
23
28
24
- function SchedulingEventInfo ( { eventInfo} : { eventInfo : SchedulingEvent } ) {
25
- const { viewUrlSourceFunction} = useContext ( ViewSourceContext ) ;
29
+ type SchedulingEventProps = { |
30
+ eventInfo : SchedulingEvent ,
31
+ | } ;
26
32
27
- const componentStack = eventInfo . componentStack
28
- ? stackToComponentSources ( eventInfo . componentStack )
29
- : null ;
33
+ function SchedulingEventInfo ( { eventInfo} : SchedulingEventProps ) {
34
+ const { viewUrlSourceFunction} = useContext ( ViewSourceContext ) ;
35
+ const { componentName, timestamp} = eventInfo ;
36
+ const componentStack = eventInfo . componentStack || null ;
30
37
31
38
const viewSource = source => {
32
39
if ( viewUrlSourceFunction != null && source != null ) {
@@ -35,45 +42,66 @@ function SchedulingEventInfo({eventInfo}: {eventInfo: SchedulingEvent}) {
35
42
} ;
36
43
37
44
return (
38
- < div className = { styles . Content } tabIndex = { 0 } >
39
- { componentStack ? (
40
- < ol className = { styles . List } >
41
- { componentStack . map ( ( [ displayName , source ] , index ) => {
42
- const hasSource = source != null ;
43
-
44
- return (
45
- < li
46
- key = { index }
47
- className = { styles . ListItem }
48
- data-source = { hasSource } >
49
- < label className = { styles . Label } >
50
- < Button
51
- className = { styles . Button }
52
- onClick = { ( ) => viewSource ( source ) } >
53
- { displayName }
54
- </ Button >
55
- { hasSource && (
56
- < ButtonIcon className = { styles . Source } type = "view-source" />
57
- ) }
58
- </ label >
59
- </ li >
60
- ) ;
61
- } ) }
62
- </ ol >
63
- ) : null }
64
- </ div >
45
+ < >
46
+ < div className = { styles . Toolbar } >
47
+ { componentName } { getSchedulingEventLabel ( eventInfo ) }
48
+ </ div >
49
+ < div className = { styles . Content } tabIndex = { 0 } >
50
+ < ul className = { styles . List } >
51
+ < li className = { styles . ListItem } >
52
+ < label className = { styles . Label } > Timestamp</ label > :{ ' ' }
53
+ < span className = { styles . Value } > { formatTimestamp ( timestamp ) } </ span >
54
+ </ li >
55
+ { componentStack && (
56
+ < li className = { styles . ListItem } >
57
+ < div className = { styles . Row } >
58
+ < label className = { styles . Label } > Rendered by</ label >
59
+ < Button
60
+ onClick = { ( ) => copy ( componentStack ) }
61
+ title = "Copy component stack to clipboard" >
62
+ < ButtonIcon type = "copy" />
63
+ </ Button >
64
+ </ div >
65
+ < ul className = { styles . List } >
66
+ { stackToComponentSources ( componentStack ) . map (
67
+ ( [ displayName , source ] , index ) => {
68
+ return (
69
+ < li key = { index } >
70
+ < Button
71
+ className = {
72
+ source
73
+ ? styles . ClickableSource
74
+ : styles . UnclickableSource
75
+ }
76
+ disabled = { ! source }
77
+ onClick = { ( ) => viewSource ( source ) } >
78
+ { displayName }
79
+ </ Button >
80
+ </ li >
81
+ ) ;
82
+ } ,
83
+ ) }
84
+ </ ul >
85
+ </ li >
86
+ ) }
87
+ </ ul >
88
+ </ div >
89
+ </ >
65
90
) ;
66
91
}
67
92
68
93
export default function SidebarEventInfo ( _ : Props ) {
69
94
const { selectedEvent} = useContext ( TimelineContext ) ;
70
95
// (TODO) Refactor in next PR so this supports multiple types of events
71
- return selectedEvent ? (
72
- < >
73
- < div className = { styles . Toolbar } > Event Component Tree</ div >
74
- { selectedEvent . schedulingEvent ? (
75
- < SchedulingEventInfo eventInfo = { selectedEvent . schedulingEvent } />
76
- ) : null }
77
- </ >
78
- ) : null ;
96
+ if ( selectedEvent ) {
97
+ return (
98
+ < >
99
+ { selectedEvent . schedulingEvent ? (
100
+ < SchedulingEventInfo eventInfo = { selectedEvent . schedulingEvent } />
101
+ ) : null }
102
+ </ >
103
+ ) ;
104
+ }
105
+
106
+ return null ;
79
107
}
0 commit comments