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 review #7127

Merged
merged 20 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
4 changes: 3 additions & 1 deletion doc/developer_guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ All available tasks can be found by running `pixi task list`, the following sect

### Editable install

It can be advantageous to install the Panel in [editable mode](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs):
It can be advantageous to install Panel in [editable mode](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs):

```bash
pixi run install
Expand All @@ -97,6 +97,8 @@ Currently, this needs to be run for each environment. So, if you want to install
pixi run -e test-ui install
```

You can find the list of environments in the **pixi.toml** file.

:::

## Linting
Expand Down
2 changes: 1 addition & 1 deletion doc/explanation/components/reactive_html_components.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This page will walk you through using the `ReactiveHTML` class to craft custom c

A *`ReactiveHTML` component* is essentially a class that you create by inheriting from the `ReactiveHTML` class. Within this custom class, you are required to define the `_template` attribute using HTML, which serves as the *design blueprint* for your custom component. You can use Javascript *template variables* `${...}` as well as Python [Jinja2](https://jinja.palletsprojects.com) syntax to make the template *dynamic*.

Here is a basic `SlideShow` component
Here is a basic `Slideshow` component

```{pyodide}
import param
Expand Down
2 changes: 1 addition & 1 deletion doc/how_to/custom_components/esm/callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ In this guide we will show you how to add callbacks to your ESM components.

## Slideshow with Python callback

This example shows you how to create a `SlideShow` component that uses a Python *callback* function to update the `Slideshow` image when its clicked:
This example shows you how to create a `Slideshow` component that uses a Python *callback* function to update the `Slideshow` image when its clicked:

```{pyodide}
import param
Expand Down
11 changes: 6 additions & 5 deletions doc/how_to/custom_components/esm/custom_widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export function render({ model }) {
const [image] = model.useState("image");

return (
<button onClick={e => setClicks(clicks+1)} class="pn-container center-content">
<img src={image} class="image-size" src={ image }/>
<button onClick={e => setClicks(clicks+1)} className="pn-container center-content">
<img src={image} className="image-size" src={ image }/>
</button>
)
}
Expand Down Expand Up @@ -129,7 +129,7 @@ export function render({ model }) {
button = ImageButton(
image="https://panel.holoviz.org/_static/logo_stacked.png",
styles={"border": "2px solid lightgray"},
width=400, height=200
width=400
)
pn.Column(button, button.param.clicks).servable()
```
Expand All @@ -141,6 +141,7 @@ import panel as pn
import param

from panel.custom import AnyWidgetComponent
from panel.widgets import WidgetBase

pn.extension()

Expand Down Expand Up @@ -208,7 +209,7 @@ pn.Column(button, button.param.clicks).servable()

If you don't want the *button* styling, you can change the `<button>` tag to a `<div>` tag.

The `ImageButton` now works as any other widget. Lets try the `.from_param` method to create a `ImageButton` from a `param` class.
The `ImageButton` now works as any other widget. Lets try the `.from_param` method to create an `ImageButton` from a `Parameter:

```{pyodide}
class MyClass(param.Parameterized):
Expand All @@ -223,7 +224,7 @@ class MyClass(param.Parameterized):
self.clicks += 1

my_instance = MyClass()
button2 = ImageButton.from_param(my_instance.param.value)
button2 = ImageButton.from_param(my_instance.param.value, image="https://panel.holoviz.org/_static/logo_stacked.png",)
pn.Column(button2, my_instance.param.clicks).servable()
```

Expand Down
4 changes: 0 additions & 4 deletions doc/how_to/custom_components/esm/dataframe.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class GridJS(JSComponent):

object = param.DataFrame()

_extension_name = 'gridjs'

_esm = """
import * as gridjs from "https://esm.sh/[email protected]"

Expand Down Expand Up @@ -86,8 +84,6 @@ class GridJS(ReactComponent):

object = param.DataFrame()

_extension_name = 'gridjs'

_esm = """
import { useEffect, useState } from "react"
import { Grid } from "https://esm.sh/[email protected]"
Expand Down
4 changes: 2 additions & 2 deletions doc/how_to/custom_components/examples/esm_leaflet.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ class LeafletHeatMap(JSComponent):
}"""

_stylesheets = ['https://unpkg.com/[email protected]/dist/leaflet.css']

pn.extension(template='bootstrap')
```

Some of the concepts this component demonstrates:
Expand All @@ -95,6 +93,8 @@ Some of the concepts this component demonstrates:
Now let's try this component:

```{pyodide}
pn.extension(template='bootstrap')

url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv"

earthquakes = pd.read_csv(url)
Expand Down
31 changes: 26 additions & 5 deletions doc/how_to/custom_components/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,16 @@ examples/table_viewer

## ESM Components

Build custom components in Javascript using so called ESM components, which allow you to write components that automatically sync parameter state between Python and JS. ESM components can be written in pure JS, using React or using the AnyWidget specification.
Build custom components in Javascript using so called ESM components, which allow you to write components that automatically sync parameter state between Python and JS. ESM components can be written in pure JavaScript, using [React](https://react.dev/) or using the [AnyWidget](https://anywidget.dev/) specification.

ESM Components is our 2nd generation api for custom components while `ReactiveHTML` is our 1st generation. We recommend using ESM Components over `ReactiveHTML`.

::::{grid} 1 2 2 3
:gutter: 1 1 1 2

<<<<<<< HEAD
:::{grid-item-card} {octicon}`columns;2.5em;sd-mr-1 sd-animate-grow50` Layouts
=======

:::{grid-item-card} {octicon}`tools;2.5em;sd-mr-1 sd-animate-grow50` Building and Bundling ESM components
:link: esm/build
Expand All @@ -81,17 +86,32 @@ How to create a custom widget using ESM components
:::

:::{grid-item-card} {octicon}`columns;2.5em;sd-mr-1 sd-animate-grow50` Create Custom Layouts
>>>>>>> 6c045a3c782a3c846ac706863e8d93c0053e2e2f
:link: esm/custom_layout
:link-type: doc

How to create a custom layout using ESM components
How to create custom layouts using ESM components
:::

:::{grid-item-card} {octicon}`arrow-left;2.5em;sd-mr-1 sd-animate-grow50` Callbacks
:link: esm/callbacks
:link-type: doc

How to add JS and Python based callbacks to ESM components.
:::

:::{grid-item-card} {octicon}`table;2.5em;sd-mr-1 sd-animate-grow50` Render a `DataFrame`
:::{grid-item-card} {octicon}`single-select;2.5em;sd-mr-1 sd-animate-grow50` Widgets
:link: esm/custom_widgets
:link-type: doc

How to create input widgets using ESM components
:::

:::{grid-item-card} {octicon}`table;2.5em;sd-mr-1 sd-animate-grow50` DataFrame
:link: esm/dataframe
:link-type: doc

How to create `JSComponent`s and `ReactComponent`s that render data in a DataFrame.
How to create ESM components that render data a DataFrame.
:::

::::
Expand Down Expand Up @@ -197,7 +217,8 @@ How to create input widgets using `ReactiveHTML`
:link: reactive_html/reactive_html_dataframe
:link-type: doc

How to create components using `ReactiveHTML` and a DataFrame parameter
How to create `ReactiveHTML` components that render data a DataFrame.

:::

::::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This approach lets you quickly build custom HTML components with complex interac

## Slideshow with Javascript Callback

This example shows you how to create a `SlideShow` component that uses a Javascript *callback* function to update the `SlideShow` image when its clicked:
This example shows you how to create a `Slideshow` component that uses a Javascript *callback* function to update the `Slideshow` image when its clicked:

```{pyodide}
import param
Expand Down
28 changes: 11 additions & 17 deletions doc/how_to/migrate/anywidget/index.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Converting from AnyWidget to Panel

This guide addresses how to convert [AnyWidget](https://anywidget.dev/) widgets to custom Panel widgets.
This guide addresses how to convert [AnyWidget](https://anywidget.dev/) widgets to custom `JSComponent` or `ReactComponent` widgets.

Please note that AnyWidget widgets are [`ipywidgets`](https://ipywidgets.readthedocs.io/en/stable/) and can be used directly in Panel via the [`IpyWidgets`](../../reference/panes/IPyWidget.ipynb) pane and the `Traitlets` `@observe` API without a conversion. We recommend trying this option first. If it does not work for your use case, please consider contributing to the existing `AnyWidget` before converting it to a Panel widget.

Some reasons you might still want to convert an `AnyWidget` to a custom Panel widget are:

- Familiar and Optimized API: This enables your and your users to use the familiar `Param` parameter API for which Panel is optimized.
- Customization: You might want to use the `AnyWidget` as a starting point and customize it to your exact needs.
- Efficiency: You users avoid loading `AnyWidget`/`ipywidgets` JavaScript libraries which ANECDOTALLY is not insignificant. Your users also avoid the overhead of converting between `Param/Panel/Bokeh` and `Traitlets`/`AnyWidget`/`ipywidgets` objects: ANECDOTALLY, Panel (i.e., Bokeh) utilizes faster serialization and deserialization methods and formats. IS THIS TRUE, PHILIPP? ALSO, WHEN USING THE ANYWIDGET ON THE BOKEH SERVER? DO WE HAVE NUMBERS FOR THIS?
- **Familiar and Optimized API**: This enables you and your users to use the familiar `Param` parameter API for which Panel is optimized.
- **Customization**: You might want to use the `AnyWidget` as a starting point and customize it to your exact needs.
- **Efficiency**: You users avoid loading `AnyWidget`/`ipywidgets` JavaScript libraries which ANECDOTALLY is not insignificant. Your users also avoid the overhead of converting between `Param/Panel/Bokeh` and `Traitlets`/`AnyWidget`/`ipywidgets` objects: ANECDOTALLY, Panel (i.e., Bokeh) utilizes faster serialization and deserialization methods and formats. IS THIS TRUE, PHILIPP? ALSO, WHEN USING THE ANYWIDGET ON THE BOKEH SERVER? DO WE HAVE NUMBERS FOR THIS?

## Conversion Steps

Expand All @@ -18,7 +18,7 @@ The high-level steps needed for converting `AnyWidgets` components to Panel comp

#### Step 1: Base Class Conversion

Convert from the `AnyWidget` base class to the Panel [`JSComponent`](../../reference/panes/JSComponent.md) base class. If the `_esm` script is based on [React](https://react.dev/), use the [`ReactComponent`](../../reference/panes/ReactComponent.md). For [Preact](https://preactjs.com/), use the [`PreactComponent`](../../reference/panes/JSComponent.md).
Convert from the `AnyWidget` base class to the Panel [`JSComponent`](../../reference/panes/JSComponent.ipynb) base class. If the `_esm` script is based on [React](https://react.dev/), use the [`ReactComponent`](../../reference/panes/ReactComponent.ipynb).

#### Step 2: Attribute Conversion

Expand Down Expand Up @@ -49,9 +49,9 @@ Their methods are also different reflecting differences between Traitlets and Pa

| AnyWidget | Panel/ Bokeh |
| --------- | ----- |
| `model.get('some_value')` | `data.some_value`|
| `model.save('some_value', 1)`<br>`model.save_changes()` | `data.some_value = 1`|
| `model.on("change:some_value", () => {...})` | `data.on('change: some_value', () => {...}))` |
| `model.get('some_value')` | `model.some_value`|
| `model.save('some_value', 1)`<br>`model.save_changes()` | `model.some_value = 1`|
| `model.on("change:some_value", () => {...})` | `model.on('change: some_value', () => {...}))` |

### Convert React Code

Expand Down Expand Up @@ -99,7 +99,7 @@ class CounterWidget(anywidget.AnyWidget):
"""
```

#### Panel `CounterWidget`
#### Panel JS `CounterWidget`

```{pyodide}
import panel as pn
Expand All @@ -121,7 +121,7 @@ class CounterButton(JSComponent):
btn.addEventListener("click", () => {
model.value += 1
});
data.on('change:value', () => {
model.on('change:value', () => {
btn.innerHTML = `count is ${model.value}`;
})
return btn
Expand All @@ -134,16 +134,10 @@ CounterButton().servable()

:::{note}

With Panel you may replace the lines `export function render({ data })` and `return btn` with the lines `export function render({ data, el })` and `el.appendChild(btn)`, if you want to minimize the number of changes.
With Panel you may replace the lines `export function render({ model })` and `return btn` with the lines `export function render({ model, el })` and `el.appendChild(btn)`, if you want to minimize the number of changes.

:::

### React Counter Widget

#### AnyWidget React `CounterWidget`

To be determined (TBD).

#### Panel React `CounterWidget`

```{pyodide}
Expand Down
4 changes: 0 additions & 4 deletions doc/how_to/param/custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ pn.Param(CustomExample.param, widgets={

However it is also possible to explicitly construct a widget from a parameter using the `.from_param` method, which makes it easy to override widget settings using keyword arguments:


```{pyodide}
pn.widgets.RadioBoxGroup.from_param(CustomExample.param.select_string, inline=True)
```
Expand All @@ -58,7 +57,6 @@ pn.widgets.RadioBoxGroup.from_param(CustomExample.param.select_string, inline=Tr

By default, a param Pane has a title that is derived from the class name of its `Parameterized` object. Using the ``name`` keyword we can set any title to the pane, e.g. to improve the user interface.


```{pyodide}
pn.Param(CustomExample.param, name="Custom Name")
```
Expand All @@ -67,14 +65,12 @@ pn.Param(CustomExample.param, name="Custom Name")

You can sort the widgets alphabetically by setting `sort=True`


```{pyodide}
pn.Param(CustomExample.param, sort=True, name="Sort by Label Example")
```

You can also specify a custom sort function that takes the (parameter name, Parameter instance) as input.


```{pyodide}
def sort_func(x):
return len(x[1].label)
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorials/basic/layouts.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Layouts Content
# Layout Content

Welcome to our guide on layouting Python objects, including Panel components! Let's dive into arranging your content in a visually appealing and organized manner.

Expand Down
2 changes: 1 addition & 1 deletion doc/tutorials/expert/custom_components.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ In this tutorial we will build a *[Mario](https://mario.nintendo.com/) style but

![Mario chime button](https://assets.holoviz.org/panel/tutorials/ipymario.gif)

This tutorial draws heavily on the great [`ipymario` tutorial](https://youtu.be/oZhyilx3gqI?si=dFPFiHua4TuuqCpu) by [Trevor Manzt](https://github.com/manzt).
This tutorial draws heavily on the great [`ipymario` tutorial](https://youtu.be/oZhyilx3gqI?si=dFPFiHua4TuuqCpu) by [Trevor Manz](https://github.com/manzt).

## Overview

Expand Down
4 changes: 2 additions & 2 deletions examples/reference/chat/ChatAreaInput.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
"\n",
"#### Parameters:\n",
"\n",
"For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
"For layout and styling-related parameters see the [Control the size](../../tutorials/basic/size.md), [Align Content](../../tutorials/basic/align.md) and [Style](../../tutorials/basic/style.md) tutorials.\n",
"\n",
"##### Core\n",
"\n",
"* **``disabled_enter``** (bool): If True, disables sending the message by pressing the `enter_sends` key.\n",
"* **``enter_sends``** (bool): If True, pressing the Enter key sends the message, if False it is sent by pressing the Ctrl-Enter. Defaults to True.",
"* **``enter_sends``** (bool): If True, pressing the Enter key sends the message, if False it is sent by pressing the Ctrl-Enter. Defaults to True.\n",
"* **``value``** (str): The value when the \"Enter\" or \"Ctrl-Enter\" key is pressed. Only to be used with `watch` or `bind` because the `value` resets to `\"\"` after the message is sent; use `value_input` instead to access what's currently available in the text input box.\n",
"* **``value_input``** (str): The current value updated on every key press.\n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion examples/reference/chat/ChatMessage.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"\n",
"#### Parameters:\n",
"\n",
"For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n",
"For layout and styling-related parameters see the [Control the size](../../tutorials/basic/size.md), [Align Content](../../tutorials/basic/align.md) and [Style](../../tutorials/basic/style.md) tutorials.\n",
"\n",
"##### Core\n",
"\n",
Expand Down
Loading
Loading