Skip to content

Commit a02a747

Browse files
committed
Add generate_prop_type
1 parent a354a73 commit a02a747

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# tsx components don't have the `.propTypes` property set
2+
# Generate it instead with the provided metadata.json
3+
# for them to be able to report invalid prop
4+
5+
import os
6+
7+
8+
prop_type_file_template = """// AUTOGENERATED FILE - DO NOT EDIT
9+
10+
var PropTypes = window.PropTypes;
11+
12+
13+
{components_prop_types}
14+
"""
15+
16+
component_prop_types_template = (
17+
"window['{package_name}'].{component_name}.propTypes = {prop_types}"
18+
)
19+
20+
21+
def generate_type(type_name):
22+
def wrap(*_):
23+
return f"PropTypes.{type_name}"
24+
25+
return wrap
26+
27+
28+
def generate_union(prop_info):
29+
types = [generate_prop_type(t) for t in prop_info["value"]]
30+
return f"PropTypes.oneOfType([{','.join(types)}])"
31+
32+
33+
def generate_shape(prop_info):
34+
props = []
35+
for key, value in prop_info["value"].items():
36+
props.append(f"{key}:{generate_prop_type(value)}")
37+
inner = "{" + ",".join(props) + "}"
38+
return f"PropTypes.shape({inner})"
39+
40+
41+
def generate_array_of(prop_info):
42+
inner_type = generate_prop_type(prop_info["value"])
43+
return f"PropTypes.arrayOf({inner_type})"
44+
45+
46+
def generate_any(*_):
47+
return "PropTypes.any"
48+
49+
50+
def generate_enum(prop_info):
51+
values = str([v["value"] for v in prop_info["value"]])
52+
return f"PropTypes.oneOf({values})"
53+
54+
55+
def generate_object_of(prop_info):
56+
return f"PropTypes.objectOf({generate_prop_type(prop_info['value'])})"
57+
58+
59+
def generate_tuple(*_):
60+
# PropTypes don't have a tuple... just generate an array.
61+
return "PropTypes.array"
62+
63+
64+
prop_types = {
65+
"array": generate_type("array"),
66+
"arrayOf": generate_array_of,
67+
"object": generate_type("object"),
68+
"shape": generate_shape,
69+
"exact": generate_shape,
70+
"string": generate_type("string"),
71+
"bool": generate_type("bool"),
72+
"number": generate_type("number"),
73+
"node": generate_type("node"),
74+
"func": generate_any,
75+
"element": generate_type("element"),
76+
"union": generate_union,
77+
"any": generate_any,
78+
"custom": generate_any,
79+
"enum": generate_enum,
80+
"objectOf": generate_object_of,
81+
"tuple": generate_tuple,
82+
}
83+
84+
85+
def generate_prop_type(prop_info):
86+
return prop_types[prop_info["name"]](prop_info)
87+
88+
89+
def generate_prop_types(
90+
metadata,
91+
package_name,
92+
):
93+
patched = []
94+
95+
for component_path, data in metadata.items():
96+
filename = component_path.split("/")[-1]
97+
extension = filename.split("/")[-1].split(".")[-1]
98+
if extension != "tsx":
99+
continue
100+
101+
component_name = filename.split(".")[0]
102+
103+
props = []
104+
for prop_name, prop_data in data.get("props", {}).items():
105+
props.append(f" {prop_name}:{generate_prop_type(prop_data['type'])}")
106+
107+
patched.append(
108+
component_prop_types_template.format(
109+
package_name=package_name,
110+
component_name=component_name,
111+
prop_types="{" + ",\n".join(props) + "}",
112+
)
113+
)
114+
115+
if patched:
116+
with open(
117+
os.path.join(package_name, "proptypes.js"), encoding="utf-8", mode="w"
118+
) as f:
119+
f.write(
120+
prop_type_file_template.format(
121+
components_prop_types="\n\n".join(patched)
122+
)
123+
)

dash/development/component_generator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from ._py_components_generation import generate_classes_files
1919
from ._jl_components_generation import generate_struct_file
2020
from ._jl_components_generation import generate_module
21+
from ._generate_prop_types import generate_prop_types
2122

2223
reserved_words = [
2324
"UNDEFINED",
@@ -135,6 +136,8 @@ def generate_components(
135136

136137
components = generate_classes_files(project_shortname, metadata, *generator_methods)
137138

139+
generate_prop_types(metadata, project_shortname)
140+
138141
with open(
139142
os.path.join(project_shortname, "metadata.json"), "w", encoding="utf-8"
140143
) as f:

0 commit comments

Comments
 (0)