Skip to content

Commit 36a8ea9

Browse files
authored
Merge pull request #131 from plotly/components_integration
Core Components Integration
2 parents a5da67b + f59aae9 commit 36a8ea9

File tree

69 files changed

+1083
-131858
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1083
-131858
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ Manifest.toml
1111
docs/build
1212
venv
1313
*.pyc
14-
tmp
14+
tmp
15+
gen_resources/build

Artifacts.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[dash_resources]
2+
git-tree-sha1 = "c857e355d2c21dfc458fb315371431dda2506109"
3+
4+
[[dash_resources.download]]
5+
sha256 = "4ff3910a8ff1f5420784397cfc6ad80341bbe03f1010eab38dcb9b8ce2423310"
6+
url = "https://github.com/plotly/DashCoreResources/releases/download/v2.0.0+0/DashCoreResources.v2.0.0.tar.gz"

Project.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Dash"
22
uuid = "1b08a953-4be3-4667-9a23-3db579824955"
33
authors = ["Chris Parmer <[email protected]>", "Alexandr Romanenko <[email protected]>"]
4-
version = "0.1.6"
4+
version = "1.0.0"
55

66
[deps]
77
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
@@ -14,24 +14,26 @@ HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
1414
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
1515
JSON2 = "2535ab7d-5cd8-5a07-80ac-9b1792aadce3"
1616
MD5 = "6ac74813-4b46-53a4-afec-0b5dc9d7885c"
17+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
1718
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
1819
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
1920
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2021
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
22+
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
2123

2224
[compat]
2325
CodecZlib = "0.6, 0.7"
2426
DashBase = "0.1"
25-
DashCoreComponents = "1.16.0"
26-
DashHtmlComponents = "1.1.3"
27-
DashTable = "4.11.3"
27+
DashCoreComponents = "2.0.0"
28+
DashHtmlComponents = "2.0.0"
29+
DashTable = "5.0.0"
2830
DataStructures = "0.17, 0.18"
2931
HTTP = "0.8.10, 0.9"
3032
JSON = "0.21"
3133
JSON2 = "0.3"
3234
MD5 = "0.2"
3335
PlotlyBase = "0.8.5, 0.8.6"
34-
julia = "1.2"
36+
julia = "1.3"
3537

3638
[extras]
3739
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

gen_resources/Project.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[deps]
2+
Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d"
3+
GitHub = "bc5e4493-9b4d-5f90-b8aa-2b2bcaad7a26"
4+
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
5+
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
6+
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
7+
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
8+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
9+
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
10+
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
11+
Tar = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
12+
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
13+
ghr_jll = "07c12ed4-43bc-5495-8a2a-d5838ef8d533"

gen_resources/Sources.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[deploy]
2+
repo = "plotly/DashCoreResources"
3+
[dash]
4+
url = "https://github.com/plotly/dash.git"
5+
tag = "v2.0.0"
6+
[dash_renderer]
7+
module = "dash_renderer"
8+
resources_path = "."
9+
[components]
10+
[components.dash_html_components]
11+
module = "dash.html"
12+
prefix = "html"
13+
resources_path = ".."
14+
metadata_file = "metadata.json"
15+
[components.dash_core_components]
16+
module = "dash.dcc"
17+
prefix = "dcc"
18+
resources_path = ".."
19+
metadata_file = "metadata.json"
20+
[components.dash_table]
21+
module = "dash.dash_table"
22+
prefix = "dash"
23+
resources_path = ".."
24+
metadata_file = "metadata.json"

gen_resources/generate.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import TOML
2+
using OrderedCollections
3+
using Conda
4+
using PyCall
5+
import YAML
6+
using Pkg.Artifacts
7+
import GitHub
8+
import GitHub: gh_get_json, DEFAULT_API
9+
using HTTP
10+
import JSON
11+
using ghr_jll
12+
13+
include("generator/generator.jl")
14+
15+
sources = TOML.parsefile(joinpath(@__DIR__, "Sources.toml"))
16+
17+
build_dir = joinpath(@__DIR__, "build")
18+
19+
artifact_file = joinpath(@__DIR__, "..", "Artifacts.toml")
20+
21+
generate(ARGS, sources, build_dir, artifact_file)

gen_resources/generator/components.jl

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
using JSON3
2+
function process_components_meta(metafile)
3+
metadata = JSON3.read(
4+
read(metafile, String)
5+
)
6+
result = []
7+
for (file, props) in metadata
8+
name = split(split(string(file), "/")[end], ".")[1]
9+
push!(result, make_component_meta(name, props))
10+
end
11+
return result
12+
end
13+
14+
function make_component_meta(name, props)
15+
args = filter(filter_arg, props["props"])
16+
regular_args = filter(collect(keys(args))) do name
17+
!endswith(string(name), "-*")
18+
end
19+
wild_args =
20+
filter(collect(keys(args))) do name
21+
endswith(string(name), "-*")
22+
end
23+
return OrderedDict(
24+
:name => Symbol(name),
25+
:args => regular_args,
26+
:wild_args => [Symbol(replace(string(a), "-*"=>"")) for a in wild_args],
27+
:docstr => docstring(name, args, props["description"]),
28+
)
29+
end
30+
31+
32+
const _reserved_words = Set(
33+
["baremodule",
34+
"begin",
35+
"break",
36+
"catch",
37+
"const",
38+
"continue",
39+
"do",
40+
"else",
41+
"elseif",
42+
"end",
43+
"export",
44+
"false",
45+
"finally",
46+
"for",
47+
"function",
48+
"global",
49+
"if",
50+
"import",
51+
"let",
52+
"local",
53+
"macro",
54+
"module",
55+
"quote",
56+
"return",
57+
"struct",
58+
"true",
59+
"try",
60+
"using",
61+
"while"]
62+
)
63+
function is_reserved_world(w)
64+
return w in _reserved_words
65+
end
66+
67+
function filter_arg(argpair)
68+
name, props = argpair
69+
is_reserved_world(name) && return false
70+
if haskey(props, "type")
71+
arg_type = props["type"]["name"]
72+
return !in(arg_type, ["func", "symbol", "instanceOf"])
73+
end
74+
if "flowType" in props
75+
arg_type_name = props["flowType"]["name"]
76+
if arg_type_name == "signature"
77+
# This does the same as the PropTypes filter above, but "func"
78+
# is under "type" if "name" is "signature" vs just in "name"
79+
if !in("type", props["FlowType"]) || props["FlowType"]["type"] != "object"
80+
return false
81+
end
82+
end
83+
return true
84+
end
85+
return false
86+
end
87+
88+
function docstring(name, props, description)
89+
article = lowercase(first(name)) in ['a', 'e', 'i', 'o', 'u'] ? "An " : "A "
90+
result = string(
91+
article, name, " component", "\n",
92+
description, "\n\n"
93+
)
94+
if haskey(props, :children)
95+
result *= arg_docstring("children", props[:children]) * "\n"
96+
end
97+
if haskey(props, :id)
98+
result *= arg_docstring("id", props[:id]) * "\n"
99+
end
100+
other_props = sort(
101+
collect(filter(v->!in(v.first, [:children, :id]), props)),
102+
lt = (a, b) -> a[1] < b[1]
103+
)
104+
result *= join(arg_docstring.(other_props), "\n")
105+
return result
106+
107+
end
108+
109+
_jl_type(::Val{:array}, type_object) = "Array"
110+
_jl_type(::Val{:bool}, type_object) = "Bool"
111+
_jl_type(::Val{:string}, type_object) = "String"
112+
_jl_type(::Val{:object}, type_object) = "Dict"
113+
_jl_type(::Val{:any}, type_object) = "Bool | Real | String | Dict | Array"
114+
_jl_type(::Val{:element}, type_object) = "dash component"
115+
_jl_type(::Val{:node}, type_object) = "a list of or a singular dash component, string or number"
116+
117+
_jl_type(::Val{:enum}, type_object) = join(
118+
string.(
119+
getindex.(type_object["value"], :value)
120+
), ", "
121+
)
122+
123+
function _jl_type(::Val{:union}, type_object)
124+
join(
125+
filter(a->!isempty(a), jl_type.(type_object["value"])),
126+
" | "
127+
)
128+
end
129+
130+
function _jl_type(::Val{:arrayOf}, type_object)
131+
result = "Array"
132+
if type_object["value"] != ""
133+
result *= string(" of ", jl_type(type_object["value"]), "s")
134+
end
135+
return result
136+
end
137+
138+
_jl_type(::Val{:objectOf}, type_object) =
139+
string("Dict with Strings as keys and values of type ", jl_type(type_object["value"]))
140+
141+
function _jl_type(::Val{:shape}, type_object)
142+
child_names = join(string.(keys(type_object["value"])), ", ")
143+
result = "lists containing elements $(child_names)"
144+
result *= join(
145+
[
146+
arg_docstring(name, prop, prop["required"], get(prop, "description", ""), 1)
147+
for (name, prop) in type_object["value"]
148+
]
149+
)
150+
return result
151+
end
152+
_jl_type(::Val{:exact}, type_object) = _jl_type(Val(:shape), type_object)
153+
_jl_type(val, type_object) = ""
154+
155+
156+
jl_type(type_object) = _jl_type(Val(Symbol(type_object["name"])), type_object)
157+
158+
arg_docstring(name_prop::Pair, indent_num = 0) = arg_docstring(name_prop[1], name_prop[2], indent_num)
159+
arg_docstring(name, prop, indent_num = 0) =
160+
arg_docstring(
161+
string(name),
162+
haskey(prop, "type") ? prop["type"] : prop["flowType"],
163+
prop["required"],
164+
prop["description"],
165+
indent_num
166+
)
167+
168+
function arg_docstring(prop_name, type_object, required, description, indent_num)
169+
typename = jl_type(type_object)
170+
indent_spacing = repeat(" ", indent_num)
171+
if occursin("\n", typename)
172+
return string(
173+
indent_spacing, "- `", prop_name, "` ",
174+
"(", required ? "required" : "optional", "):",
175+
description, ". ",
176+
prop_name, " has the following type: ", typename
177+
)
178+
end
179+
180+
return string(
181+
indent_spacing, "- `", prop_name, "` ",
182+
"(",
183+
isempty(typename) ? "" : string(typename, "; "),
184+
required ? "required" : "optional",
185+
")",
186+
isempty(description) ? "" : string(": ", description)
187+
)
188+
end

0 commit comments

Comments
 (0)