Skip to content
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

docs: Component Rules #1055

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Binary file added plugins/ui/docs/_assets/component_rules_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added plugins/ui/docs/_assets/component_rules_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
130 changes: 130 additions & 0 deletions plugins/ui/docs/describing/component_rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Component Rules

This guide presents some important rules to remember for `deephaven.ui` components when writing queries.

## Children and props

Arguments passed to a component may be either `children` or `props`. `Children` are positional arguments passed to a `parent` component. `Props` are keyword arguments that determine the behavior and rendering style of the component. The `child` positional arguments must be passed first in the desired order. The `prop` keyword arguments can then be added in any order. Placing a `prop` before a `child` argument will cause the `child` to be out of order.

```python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image of the output?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsmmcken will this be testable with the snapshot tool if this doesn't live in docs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

from deephaven import ui

my_flex = ui.flex(
ui.heading("Heading"),
ui.button("Button"),
ui.text("Text"),
direction="column",
wrap=True,
width="200px",
)
```

![Children and props](../_assets/component_rules_1.png)

In the above example, the `flex` component is the `parent`. It has three `children`: a `heading`, a `button`, and a `text` component. These `children` will be rendered inside the `flex`. It also has three props: `direction`, `wrap`, and `width`. These three props indicate that the flex should be rendered as a 200 pixel column with wrap enabled.

## Comparison with JSX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the purpose of this section. What component rule does this demonstrate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mofojed Requested a comparison with JSX.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose is showing users familiar with React how to modify this for DH, but an intro sentence saying as much would be useful.


For developers familiar with React JSX, this example shows how `prop` and `child` arguments are specified in JSX.

```html
<MyComponent prop1="value1">Hello World</MyComponent>
```

Here is the same component written in `deephaven.ui`.

```python
my_component("Hello World", prop1="value1")
```

## Define your own children and props

To define `children` and `props` for a custom component, add them as arguments to the component function. As a convention, you may declare the children using the `*` symbol to take any number of arguments.

```python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An image of the component would be good to have.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

from deephaven import ui


@ui.component
def custom_flex(*children, is_column):
return ui.flex(
ui.heading("My Component"),
children,
direction="column" if is_column else "row",
)


my_custom_flex = custom_flex(ui.text("text"), ui.button("button"), is_column=True)
```

![Define your own children and props](../_assets/component_rules_2.png)

## Component return values

A `deephaven.ui` component usually returns a component. However, it may also return:

- a list or tuple of components.
- `None` if it should perform logic but does not need to be rendered.
- a single value like a `string` or `int`.

```python
from deephaven import ui


@ui.component
def return_component():
return ui.text("component")


@ui.component
def list_of_components():
return [ui.text("list"), ui.text("of"), ui.text("components")]


@ui.component
def return_tuple():
return (ui.text("a"), ui.text("b"))


@ui.component
def return_none():
print("return none")
return None


@ui.component
def return_string():
return "string"


@ui.component
def return_int():
return 1


my_return_component = return_component()
my_list_of_components = list_of_components()
my_return_tuple = return_tuple()
my_return_none = return_none()
my_return_string = return_string()
my_return_int = return_int()
```

## Conditional return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section feels like the same topic as the previous. Any reason not to just combine them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous section is about valid return values. This section is about returning different values based on a condition. I think it is clearer in two different sections.


Return statements can be conditional in order to render different components based on inputs.

```python
from deephaven import ui


@ui.component
def return_conditional(is_button):
if is_button:
return ui.button("button")
return ui.text("text")


my_button = return_conditional(True)
my_text = return_conditional(False)
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can link to conditional rendering. All that section has not been created yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugins / deephaven.ui docs don't have a Related docs section; so either all of them need it, or we agree not to include it for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the docs in this repo will eventually be rendered on the docs site. All of the pages on there have related documentation at the bottom. These should have it.

4 changes: 4 additions & 0 deletions plugins/ui/docs/sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
"label": "Importing and Exporting Components",
"path": "describing/importing_and_exporting_components.md"
},
{
"label": "Component Rules",
"path": "describing/component_rules.md"
},
{
"label": "Working with Tables",
"path": "describing/work_with_tables.md"
Expand Down
Loading