@@ -12,10 +12,15 @@ pure Python, there are other projects which already allow you to do this inside
12
12
or in
13
13
`webpages <https://blog.jupyter.org/and-voil%C3%A0-f6a2c08a4a93?gi=54b835a2fcce >`__.
14
14
The real power of IDOM comes from its ability to seemlessly leverage the existing
15
- ecosystem of `React components <https://reactjs.org/docs/components-and-props.html >`__.
16
- So long as you can install a React library using `Snowpack <https://www.snowpack.dev/ >`__
17
- you can use it in your IDOM layout. You can even define your own Javascript modules
18
- which use these third party Javascript packages.
15
+ ecosystem of
16
+ `React components <https://reactjs.org/docs/components-and-props.html >`__.
17
+ So long as your library of interest is an
18
+ `ES Module <https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/ >`__
19
+ you could install using
20
+ `Snowpack <https://www.snowpack.dev/ >`__
21
+ you can use it with IDOM (we're working to support non-standard packages too) [GH-166 ]_.
22
+ You can even define your own Javascript modules which use these third party Javascript
23
+ packages.
19
24
20
25
21
26
Installing React Components
@@ -29,7 +34,8 @@ Installing React Components
29
34
30
35
Once you've done this you can get started right away. In this example we'll be using a
31
36
charting library for React called `Victory <https://formidable.com/open-source/victory/ >`__.
32
- Installing it in IDOM is quite simple:
37
+ Installing it in IDOM is quite simple. Just create a :class: `~idom.widgets.utils.Module `,
38
+ tell it what to install and specify ``install=True `` (we're working on a CLI for this) [GH-167 ]_:
33
39
34
40
.. code-block ::
35
41
@@ -54,12 +60,132 @@ Using the ``VictoryBar`` chart component is as simple as displaying it:
54
60
55
61
display(VictoryBar)
56
62
63
+ The output should look something like this:
64
+
65
+ .. image :: ./static/victory_bar_default_chart.png
66
+
57
67
58
68
Passing Props To Components
59
69
---------------------------
60
70
61
- Under construction...
71
+ So now that we can install and display a dependency we probably want to pass data or
72
+ callbacks to it. This can be done in just the same way as you learned to do when
73
+ :ref: `getting started `. In the following example we'll be using a
74
+ `Button <https://react.semantic-ui.com/elements/button/ >`__
75
+ component from the
76
+ `Semantic UI <https://react.semantic-ui.com/ >`__
77
+ framework. We'll register callbacks and pass props to the ``<Button/> `` just as you
78
+ would for any other element in IDOM:
79
+
80
+ .. code-block ::
81
+
82
+ import idom
83
+
84
+ semantic_ui = idom.Module("semantic-ui-react", install=True)
85
+ Button = semantic_ui.Import("Button")
86
+
87
+ semantic_ui_style = idom.html.link(
88
+ {
89
+ "rel": "stylesheet",
90
+ "href": "//cdn.jsdelivr.net/npm/[email protected] /dist/semantic.min.css",
91
+ }
92
+ )
93
+
94
+ @idom.element
95
+ async def PrimarySecondaryButtons(self):
96
+
97
+ async def on_click_primary(event, info):
98
+ print("Primary Clicked:")
99
+ print(event)
100
+ print(info)
101
+
102
+ async def on_click_secondary(event, info):
103
+ print("Secondary Clicked:")
104
+ print(event)
105
+ print(info)
106
+
107
+ return idom.html.div(
108
+ [
109
+ semantic_ui_style,
110
+ Button({"primary": True, "onClick": on_click_primary}, ["Primary"]),
111
+ Button({"secondary": True, "onClick": on_click_secondary}, ["Secondary"]),
112
+ ]
113
+ )
114
+
115
+ display(PrimarySecondaryButtons)
116
+
117
+ Which should produce the following output when interacted with:
118
+
119
+ .. image :: ./static/primary_secondary_buttons.png
62
120
63
121
64
122
Defining Your Own Modules
65
123
-------------------------
124
+
125
+ While it's probably best to create
126
+ `a real package <https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry >`__
127
+ for your Javascript, if you're just experimenting it might be easiest to just quickly
128
+ hook in a module of your own making on the fly. As before, we'll be using a
129
+ :class: `~idom.widgets.utils.Module `, however this time we'll pass it a ``source ``
130
+ parameter which is a file-like object. In this example we'll use Victory again, but
131
+ this time we'll add a callback to it. Unfortunately we can't just pass it in
132
+ :ref: `like we did before <Passing Props To Components >` because Victory's event API
133
+ is a bit more complex so we've implemented a quick wrapper for it in a file ``chart.js ``.
134
+
135
+ .. code-block :: javascript
136
+
137
+ import React from " ./react.js" ;
138
+ import { VictoryBar , VictoryChart , VictoryTheme , Bar } from " ./victory.js" ;
139
+ import htm from " ./htm.js" ;
140
+
141
+ const html = htm .bind (React .createElement );
142
+
143
+ export default {
144
+ ClickableChart : function ClickableChart (props ) {
145
+ return html `
146
+ <${ VictoryChart}
147
+ theme=${ VictoryTheme .material }
148
+ style=${ {" style" : {" parent" : {" width" : " 500px" }}}}
149
+ domainPadding=${ 20 }
150
+ >
151
+ <${ VictoryBar}
152
+ data=${ props .data }
153
+ dataComponent=${ html `
154
+ <${ Bar}
155
+ events=${ {
156
+ onClick: props .onClick ,
157
+ }}
158
+ />
159
+ ` }
160
+ />
161
+ <//>
162
+ ` ;
163
+ },
164
+ };
165
+
166
+ Which we can read in as a ``source `` to :class: `~idom.widgets.utils.Module `:
167
+
168
+ .. code-block ::
169
+
170
+ with open("chart.js") as f:
171
+ ClickableChart = idom.Module("chart", source=f).Import("ClickableChart")
172
+
173
+ async def handle_event(event):
174
+ print(event)
175
+
176
+ data = [
177
+ {"x": 1, "y": 2},
178
+ {"x": 2, "y": 4},
179
+ {"x": 3, "y": 7},
180
+ {"x": 4, "y": 3},
181
+ {"x": 5, "y": 5},
182
+ ]
183
+
184
+ display(
185
+ ClickableChart,
186
+ {"data": data, "onClick": handle_event}
187
+ )
188
+
189
+ The above usag should then produce the following output when you click the bars in the chart:
190
+
191
+ .. image :: ./static/custom_victory_chart.png
0 commit comments