@@ -12,10 +12,15 @@ pure Python, there are other projects which already allow you to do this inside
1212or in
1313`webpages <https://blog.jupyter.org/and-voil%C3%A0-f6a2c08a4a93?gi=54b835a2fcce >`__.
1414The 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.
1924
2025
2126Installing React Components
@@ -29,7 +34,8 @@ Installing React Components
2934
3035Once you've done this you can get started right away. In this example we'll be using a
3136charting 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 ]_:
3339
3440.. code-block ::
3541
@@ -54,12 +60,132 @@ Using the ``VictoryBar`` chart component is as simple as displaying it:
5460
5561 display(VictoryBar)
5662
63+ The output should look something like this:
64+
65+ .. image :: ./static/victory_bar_default_chart.png
66+
5767
5868Passing Props To Components
5969---------------------------
6070
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
62120
63121
64122Defining Your Own Modules
65123-------------------------
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