11import { memo , useState } from "react" ;
22import { Handle , NodeProps , Position } from "reactflow" ;
3+ import compatDb from "./compat-db.json" ;
34
4- const style = {
5- // wordWrap: "break-word",
6- whiteSpace : "pre-wrap" as "pre-wrap" , // This is weird, TypoScripto...
7- padding : 4 ,
8- border : "2px solid" ,
9- background : "#0c0c0c" ,
10- color : "#fff" ,
11- width : 150 ,
12- fontSize : 11 ,
13- fontFamily : "Fira Code" ,
5+ type DTStatus = "okay" | "disabled" ;
6+
7+ type DotColor = "blue" | "red" ;
8+
9+ const getDotColor = ( status ?: DTStatus ) : DotColor | null => {
10+ switch ( status ) {
11+ case "okay" : return "blue" ;
12+ case "disabled" : return "red" ;
13+ default : return null ;
14+ }
15+ }
16+
17+ export const Dot : FC < { status ?: DTStatus } > = ( { status } ) => {
18+ if ( ! status ) {
19+ return null ;
20+ }
21+ const color = getDotColor ( status ) ;
22+ return (
23+ < div className = "dot" >
24+ < style > { `
25+ div.dot {
26+ width: 10px;
27+ height: 10px;
28+ background: ${ color } ;
29+ border-radius: 100%;
30+ }
31+ ` } </ style >
32+ </ div >
33+ ) ;
34+ } ;
35+
36+ const docsbaseUrl = "https://docs.kernel.org"
37+ const dtBaseUrl = "https://www.kernel.org/doc/Documentation/devicetree/bindings" ;
38+
39+ type DocsCategory = "binding" | "docs" ;
40+
41+ type DocsEntry = {
42+ category : DocsCategory ;
43+ path : string ;
44+ } ;
45+
46+ const getBaseUrl = ( category : DocsCategory ) : string => {
47+ switch ( category ) {
48+ case "binding" : return dtBaseUrl ;
49+ case "docs" : return docsbaseUrl ;
50+ }
51+ } ;
52+
53+ const getDocUrl = ( compat : string ) => {
54+ const res = compat . split ( ";" ) . find ( ( c ) => ! ! compatDb [ c ] ) ;
55+ if ( ! res ) {
56+ return null ;
57+ }
58+ const d = compatDb [ res ] ;
59+ const baseUrl = getBaseUrl ( d . category ) ;
60+ return `${ baseUrl } /${ d . path } ` ;
61+ }
62+
63+ const Compat : FC < { compat ?: string ; } > = ( { compat } ) => {
64+ if ( ! compat ) {
65+ return null ;
66+ }
67+ const docUrl = getDocUrl ( compat ) ;
68+
69+ if ( ! docUrl ) {
70+ return compat ;
71+ }
72+
73+ return (
74+ < a className = "compat" href = { docUrl } target = "_blank" >
75+ { compat }
76+ < style > { `
77+ a.compat {
78+ color: #cdeeff;
79+ text-decoration: underline;
80+ }
81+ ` } </ style >
82+ </ a >
83+ ) ;
84+ } ;
85+
86+ export const DataNode : FC < { data : object ; status ?: DTStatus } > = ( {
87+ data,
88+ status,
89+ } ) => {
90+ if ( ! data ) {
91+ return null ;
92+ }
93+
94+ return (
95+ < div className = "node" >
96+ < span > { data . label } </ span >
97+ < span > { data . baseAddr } </ span >
98+ < Compat compat = { data . compat } />
99+ < Dot status = { status } />
100+ < style > { `
101+ div.node {
102+ white-space: pre-wrap;
103+ padding: 4px;
104+ border: 2px solid #789789;
105+ background: #0c0c0c;
106+ color: #fff;
107+ width: 150px;
108+ font-size: 12px;
109+ font-family: "Fira Code";
110+ display: flex;
111+ flex-direction: column;
112+ }
113+ div.node:hover {
114+ border-color: #987987;
115+ border-style: dotted;
116+ }
117+ ` } </ style >
118+ </ div >
119+ ) ;
14120} ;
15121
16122const DTNode = ( {
@@ -19,27 +125,15 @@ const DTNode = ({
19125 targetPosition = Position . Top ,
20126 sourcePosition = Position . Bottom
21127} : NodeProps ) => {
22- const [ hovered , setHovered ] = useState ( false ) ;
23-
24- const hoverOn = ( ) => setHovered ( true ) ;
25- const hoverOff = ( ) => setHovered ( false ) ;
26-
27- const borderColor = hovered ? "#987987" : "#789789" ;
28- const borderStyle = hovered ? "dotted" : "solid" ;
128+ const { status, ...nData } = data ;
29129 return (
30130 < >
31131 < Handle
32132 type = "target"
33133 position = { targetPosition }
34134 isConnectable = { isConnectable }
35135 />
36- < div
37- style = { { ...style , borderColor, borderStyle } }
38- onMouseEnter = { hoverOn }
39- onMouseLeave = { hoverOff }
40- >
41- { data ?. label }
42- </ div >
136+ < DataNode data = { nData } status = { status } />
43137 < Handle
44138 type = "source"
45139 position = { sourcePosition }
0 commit comments