Skip to content

Commit 4c6abe9

Browse files
committed
improve your first component section
1 parent dfef613 commit 4c6abe9

File tree

10 files changed

+91
-132
lines changed

10 files changed

+91
-132
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from idom import component, html, run
2+
3+
4+
@component
5+
def Photo():
6+
return html.img(
7+
{
8+
"src": "https://i.pinimg.com/564x/d6/96/c4/d696c4d3db31609c1abb05c52f305ec1.jpg",
9+
"style": {"width": "30%"},
10+
"alt": "Ray Charles",
11+
}
12+
)
13+
14+
15+
@component
16+
def Gallery():
17+
return html.section(
18+
html.h1("Famous Musicians"),
19+
Photo(),
20+
Photo(),
21+
Photo(),
22+
)
23+
24+
25+
run(Gallery)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from idom import component, html, run
2+
3+
4+
@component
5+
def Photo():
6+
return html.img(
7+
{
8+
"src": "https://i.pinimg.com/564x/d6/96/c4/d696c4d3db31609c1abb05c52f305ec1.jpg",
9+
"style": {"width": "30%"},
10+
"alt": "Ray Charles",
11+
}
12+
)
13+
14+
15+
run(Photo)

docs/source/_examples/creating_interfaces/static_todo_list.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33

44
@component
5-
def App():
6-
return html.div(
7-
html.h1("My Todo List"),
8-
html.ul(
9-
html.li("Build a cool new app"),
10-
html.li("Share it with the world!"),
11-
),
5+
def Photo():
6+
return html.img(
7+
{
8+
"src": "https://i.pinimg.com/564x/d6/96/c4/d696c4d3db31609c1abb05c52f305ec1.jpg",
9+
"style": {"width": "70%", "marginLeft": "15%"},
10+
"alt": "Ray Charles",
11+
}
1212
)
1313

1414

15-
run(App)
15+
run(Photo)

docs/source/_exts/interactive_widget.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class IteractiveWidget(Directive):
1616
_next_id = 0
1717

1818
option_spec = {
19-
"no-activate-button": directives.flag,
19+
"activate-result": directives.flag,
2020
"margin": float,
2121
}
2222

@@ -40,7 +40,7 @@ def run(self):
4040
"{container_id}",
4141
"{view_id}",
4242
"{_IDOM_EXAMPLE_HOST}",
43-
{"false" if "no-activate-button" in self.options else "true"},
43+
{"false" if "activate-result" in self.options else "true"},
4444
);
4545
</script>
4646
</div>

docs/source/_exts/widget_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def _literal_include(name, linenos):
115115
def _interactive_widget(name, with_activate_button):
116116
return _interactive_widget_template.format(
117117
name=name,
118-
activate_button_opt="" if with_activate_button else ":no-activate-button:",
118+
activate_button_opt="" if with_activate_button else ":activate-result:",
119119
)
120120

121121

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
body {
2-
--admonition-title-font-size: 0.9rem !important;
3-
--admonition-font-size: 0.9rem !important;
4-
}
5-
6-
.admonition-title {
7-
font-weight: bold !important;
2+
--admonition-title-font-size: 1rem !important;
3+
--admonition-font-size: 1rem !important;
84
}

docs/source/creating-interfaces/html-with-idom.rst

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ to specify a URL to its ``src`` and use some ``style`` to modify and position it
7979
.. code-block:: html
8080

8181
<img
82-
src="https://picsum.photos/500/300"
83-
style="width: 70%; margin-left: 15%;"
82+
src="https://i.pinimg.com/564x/29/66/4d/29664d24bc793085a7671d7fc02a33f4.jpg"
83+
style="width: 50%; margin-left: 25%;"
84+
alt="Martha Argerich"
8485
/>
8586

8687
In IDOM we add these attributes to elements using dictionaries. There are some notable
@@ -92,16 +93,18 @@ Additionally, instead of specifying ``style`` using a string, we use a dictionar
9293

9394
html.img(
9495
{
95-
"src": "https://picsum.photos/500/300",
96-
"style": {"width": "70%", "marginLeft": "15%"},
96+
"src": "https://i.pinimg.com/564x/29/66/4d/29664d24bc793085a7671d7fc02a33f4.jpg
97+
"style": {"width": "50%", "marginLeft": "25%"},
98+
"alt": "Martha Argerich",
9799
}
98100
)
99101

100102
.. raw:: html
101103

102104
<img
103-
src="https://picsum.photos/500/300"
104-
style="width: 70%; margin-left: 15%;"
105+
src="https://i.pinimg.com/564x/29/66/4d/29664d24bc793085a7671d7fc02a33f4.jpg"
106+
style="width: 50%; margin-left: 25%;"
107+
alt="Martha Argerich"
105108
/>
106109

107110

docs/source/creating-interfaces/index.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,6 @@ practice we'll put the todo list HTML from above into a component:
115115
.. example:: creating_interfaces.static_todo_list
116116
:activate-result:
117117

118-
.. note::
119-
120-
Not all functions that return HTML need to be decorated with the ``@component``
121-
decorator. We'll discuss when and where they are required when we start :ref:`adding
122-
interactivity`.
123-
124118
If you explore a little bit on your own you'll find that, when called, functions which
125119
are decorated in this way don't return what you might initially expect:
126120

Lines changed: 28 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,46 @@
11
Your First Component
22
====================
33

4-
The next building block in our journey with IDOM are components. At their core,
5-
components are just a normal Python functions that return :ref:`HTML <HTML with IDOM>`.
6-
The one special thing about them that we'll concern ourselves with now, is that to
7-
create them we need to add an ``@component`` `decorator
8-
<https://realpython.com/primer-on-python-decorators/>`__. To see what this looks like in
9-
practice we'll put the todo list HTML from above into a component:
10-
11-
.. example:: creating_interfaces.static_todo_list
12-
:activate-result:
13-
14-
.. note::
15-
16-
Not all functions that return HTML need to be decorated with the ``@component``
17-
decorator. We'll discuss when and where they are required when we start :ref:`adding
18-
interactivity`.
19-
20-
In the code above we have a function ``App`` that is decorated with ``@component`` to
21-
turn it into a component. This function then gets passed to
22-
:func:`~idom.server.prefab.run` in order to :ref:`run a server <Running IDOM>` to
23-
display it. If we had not decorated our ``App`` function with the ``@component``
24-
decorator, the server would start, but as soon as we tried to view the page it would be
25-
blank. The servers logs would then indicate:
26-
27-
.. code-block:: text
28-
29-
TypeError: Expected a ComponentType, not dict.
30-
31-
To see why this is we can check out what happens when we call ``App`` with and without
32-
the ``@component`` decorator. In the first case we get a dictionary representing our
33-
HTML:
34-
35-
.. testsetup::
36-
37-
from pprint import pprint as print
38-
39-
.. testcode::
40-
41-
from idom import html
4+
As we learned :ref:`earlier <HTML with IDOM>` we can use IDOM to make rich structured
5+
documents out of standard HTML elements. As these documents become larger and more
6+
complex though, working with these tiny UI elements can become difficult. When this
7+
happens, IDOM allows you to group these elements together info "components". These
8+
components can then be reused throughout your application.
429

4310

44-
def App():
45-
return html.div(
46-
html.h1("My Todo List"),
47-
html.ul(
48-
html.li("Build a cool new app"),
49-
html.li("Share it with the world!"),
50-
),
51-
)
11+
Defining a Component
12+
--------------------
5213

14+
At their core, components are just a normal Python functions that return HTML. There's
15+
only two special things which we'll concer ourselves with there:
5316

54-
print(App())
17+
- We need to add a ``@component`` `decorator
18+
<https://realpython.com/primer-on-python-decorators/>`__
19+
to component function.
5520

56-
.. testoutput::
21+
- By convention, we name component functions like classes - with ``CamelCase``.
5722

58-
{'tagName': 'div',
59-
'children': [{'tagName': 'h1', 'children': ['My Todo List']},
60-
{'tagName': 'ul',
61-
'children': [{'tagName': 'li',
62-
'children': ['Build a cool new app']},
63-
{'tagName': 'li',
64-
'children': ['Share it with the world!']}]}]}
23+
So for example, if we wanted write and then :ref:`display <Running IDOM>` a ``Photo``
24+
component we might write:
6525

66-
But, if we decorate it we instead find:
67-
68-
.. testcode::
69-
70-
from idom import component, html, ComponentType
71-
72-
73-
@component
74-
def App():
75-
return html.div(
76-
html.h1("My Todo List"),
77-
html.ul(
78-
html.li("Build a cool new app"),
79-
html.li("Share it with the world!"),
80-
),
81-
)
82-
83-
84-
app = App()
85-
print(app)
86-
print(type(app))
87-
88-
.. testcode::
89-
:hide:
90-
91-
import re
92-
# update the output code block below and this regex pattern if this fails
93-
assert re.match("Component\(\d+\)", str(App()))
26+
.. example:: creating_interfaces.simple_photo
27+
:activate-result:
9428

95-
.. code-block:: text
29+
.. warning::
9630

97-
App(7fc0d881fbd0)
98-
<class 'idom.core.component.Component'>
31+
If we had not decorated our ``Photo`` function with the ``@component`` decorator,
32+
the server would start, but as soon as we tried to view the page it would be blank.
33+
The servers logs would then indicate:
9934

100-
After making this discovery, if you did a bit of digging around in IDOM's source code,
101-
you'd find that this ``Component`` object has a ``Component.render()`` method. And it's
102-
when calling this method, that you'll return the HTML we might have expected initially:
35+
.. code-block:: text
10336
104-
.. testcode::
37+
TypeError: Expected a ComponentType, not dict.
10538
106-
print(app.render())
10739
108-
.. testoutput::
40+
Using a Component
41+
-----------------
10942

110-
{'tagName': 'div',
111-
'children': [{'tagName': 'h1', 'children': ['My Todo List']},
112-
{'tagName': 'ul',
113-
'children': [{'tagName': 'li',
114-
'children': ['Build a cool new app']},
115-
{'tagName': 'li',
116-
'children': ['Share it with the world!']}]}]}
43+
Having defined our ``Photo`` component we can now nest it inside of other components:
11744

118-
This explains the error. If we don't decorate the function we just get out out HTML
119-
dict, but if we do, we get this special ``Component`` object back. Since the ``run()``
120-
function expects the latter to do its job, we get an error about it.
45+
.. example:: creating_interfaces.nested_photos
46+
:activate-result:

docs/source/getting-started/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ This should automatically open up a browser window to a page that looks like thi
6262
.. card::
6363

6464
.. interactive-widget:: sample_app
65-
:no-activate-button:
65+
:activate-result:
6666

6767
If you get a ``RuntimeError`` similar to the following:
6868

0 commit comments

Comments
 (0)