Skip to content

reorganize creating-interfaces + add info on fragments #685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
HTML With IDOM
==============

In a typical Python-base web application the resonsibility of defining the view along
In a typical Python-base web application the responsibility of defining the view along
with its backing data and logic are distributed between a client and server
respectively. With IDOM, both these tasks are centralized in a single place. This is
done by allowing HTML interfaces to be constructed in Python. Take a look at the two
code examples below. The one on the left shows how to make a basic title and todo list
using standard HTML, the one of the right uses IDOM in Python, and below is a view of
what the HTML would look like if displayed:
code examples below. The first one shows how to make a basic title and todo list using
standard HTML, the second uses IDOM in Python, and below is a view of what the HTML
would look like if displayed:

.. grid:: 1 1 2 2
:margin: 0
:padding: 0

.. grid-item::
:columns: 6

.. code-block:: html

Expand All @@ -25,7 +24,6 @@ what the HTML would look like if displayed:
</ul>

.. grid-item::
:columns: 6

.. testcode::

Expand Down Expand Up @@ -86,7 +84,7 @@ to specify a URL to its ``src`` and use some ``style`` to modify and position it

In IDOM we add these attributes to elements using dictionaries. There are some notable
differences though. The biggest being the fact that all names in IDOM use ``camelCase``
instead of dash-sepearted words. For example, ``margin-left`` becomes ``marginLeft``.
instead of dash-separated words. For example, ``margin-left`` becomes ``marginLeft``.
Additionally, instead of specifying ``style`` using a string, we use a dictionary:

.. testcode::
Expand Down
22 changes: 11 additions & 11 deletions docs/source/creating-interfaces/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Creating Interfaces
.. toctree::
:hidden:

html-with-idom
your-first-components
rendering-data
html-with-idom/index
your-first-components/index
rendering-data/index

.. dropdown:: :octicon:`bookmark-fill;2em` What You'll Learn
:color: info
Expand All @@ -16,20 +16,20 @@ Creating Interfaces
.. grid:: 1 2 2 2

.. grid-item-card:: :octicon:`code-square` HTML with IDOM
:link: html-with-idom
:link: html-with-idom/index
:link-type: doc

Construct HTML layouts from the basic units of user interface functionality.

.. grid-item-card:: :octicon:`package` Your First Components
:link: your-first-components
:link: your-first-components/index
:link-type: doc

Define reusable building blocks that it easier to construct complex
interfaces.

.. grid-item-card:: :octicon:`database` Rendering Data
:link: rendering-data
:link: rendering-data/index
:link-type: doc

Use data to organize and render HTML elements and components.
Expand Down Expand Up @@ -75,7 +75,7 @@ To recreate the same thing in IDOM you would write:
)

.. card::
:link: html-with-idom
:link: html-with-idom/index
:link-type: doc

:octicon:`book` Read More
Expand All @@ -94,10 +94,10 @@ create them we need to add an ``@component`` `decorator
<https://realpython.com/primer-on-python-decorators/>`__. To see what this looks like in
practice we'll quickly make a ``Photo`` component:

.. idom:: _examples/simple_photo
.. idom:: your-first-components/_examples/simple_photo

.. card::
:link: your-first-components
:link: your-first-components/index
:link-type: doc

:octicon:`book` Read More
Expand All @@ -116,10 +116,10 @@ from data in this way must be orgnized with :ref:`"keys" <Organizing Items With
One case where we might want to do this is if items in a todo list come from a list of
data that we want to sort and filter:

.. idom:: _examples/todo_list_with_keys
.. idom:: rendering-data/_examples/todo_list_with_keys

.. card::
:link: rendering-data
:link: rendering-data/index
:link-type: doc

:octicon:`book` Read More
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
def Photo(alt_text, image_id):
return html.img(
{
"src": f"https://picsum.photos/id/{image_id}/500/300",
"src": f"https://picsum.photos/id/{image_id}/500/200",
"style": {"width": "50%"},
"alt": alt_text,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from idom import component, html, run


@component
def MyTodoList():
return html.div(
html.h1("My Todo List"),
html.img({"src": "https://picsum.photos/id/0/500/300"}),
html.ul(html.li("The first thing I need to do is...")),
)


run(MyTodoList)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from idom import component, html, run


@component
def MyTodoList():
return html._(
html.h1("My Todo List"),
html.img({"src": "https://picsum.photos/id/0/500/200"}),
html.ul(html.li("The first thing I need to do is...")),
)


run(MyTodoList)
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,63 @@ component once and use it wherever and however you need to:
.. idom:: _examples/nested_photos


Return a Single Root Element
----------------------------

Components must return a "single root element". That one root element may have children,
but you cannot for example, return a list of element from a component and expect it to
be rendered correctly. If you want to return multiple elements you must wrap them in
something like a :func:`html.div <idom.html.div>`:

.. idom:: _examples/wrap_in_div

If don't want to add an extra ``div`` you can use a "fragment" instead with the
:func:`html._ <idom.html._>` function:

.. idom:: _examples/wrap_in_fragment

Fragments allow you to group elements together without leaving any trace in the UI. For
example, the first code sample written with IDOM will produce the second HTML code
block:

.. grid:: 1 2 2 2
:margin: 0
:padding: 0

.. grid-item::

.. testcode::

from idom import html

html.ul(
html._(
html.li("Group 1 Item 1"),
html.li("Group 1 Item 2"),
html.li("Group 1 Item 3"),
),
html._(
html.li("Group 2 Item 1"),
html.li("Group 2 Item 2"),
html.li("Group 2 Item 3"),
)
)

.. grid-item::

.. code-block:: html

<ul>
<li>Group 1 Item 1</li>
<li>Group 1 Item 2</li>
<li>Group 1 Item 3</li>
<li>Group 2 Item 1</li>
<li>Group 2 Item 2</li>
<li>Group 2 Item 3</li>
</ul>



Parametrizing Components
------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ combine these elements into reusable :ref:`"components" <your first components>`
sections that follow you'll learn how these UI elements are created and organized into
components. Then, you'll use this knowledge to create interfaces from raw data:

.. idom:: creating-interfaces/_examples/todo_list_with_keys
.. idom:: creating-interfaces/rendering-data/_examples/todo_list_with_keys

.. card::
:link: creating-interfaces/index
Expand Down
2 changes: 1 addition & 1 deletion tests/test_core/test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,5 +1161,5 @@ def SetStateDuringRender():
assert render_count.current == 2

# there should be no more renders to perform
with pytest.raises(asyncio.exceptions.TimeoutError):
with pytest.raises(asyncio.TimeoutError):
await asyncio.wait_for(layout.render(), timeout=0.1)