# Panel

> Un panel lateral acoplable y redimensionable. Un componente nativo de Pyzed para GUIs de escritorio en Python, con vista previa, ejemplos y su API.

Source: https://albakore.github.io/pyzed/es/library/panel/

:::tip[En pocas palabras]
Una zona lateral de la ventana, como la lista de archivos de la izquierda, que puedes ensanchar o estrechar.
:::

Un panel acoplable con una cabecera opcional. `side` decide qué borde lleva la línea; con un `width` numérico (`height` para el de abajo) ese borde se puede arrastrar para cambiar el tamaño, y `on_resize` informa del nuevo tamaño.

`ui.panel` · Categoría: [Espacio de trabajo](https://albakore.github.io/pyzed/es/library/#espacio-de-trabajo) · [Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#panel)

**Código:**

```python
pz.row([
    ui.panel(
        pz.column([ui.list_item("Inbox", on_open, icon="inbox", selected=True, inset=True),
                   ui.list_item("Archive", on_open, icon="archive", inset=True)]),
        header=ui.panel_header("Mail", [ui.icon_button("plus", on_new, size="xs")], icon="mail"),
        width=220, side="left",
    ),
    pz.container(ui.muted("Content"), center=True, width="fill", height="fill"),
], height="fill")
```

## Cuándo usarlo

- Cuando montas tu propia disposición en lugar de `ui.workspace`: barras laterales, inspectores, esquemas.

## Uso

```python
import pyzed as pz
from pyzed import ui

pz.row([
    ui.panel(
        pz.column([ui.list_item("Inbox", on_open, icon="inbox", selected=True, inset=True),
                   ui.list_item("Archive", on_open, icon="archive", inset=True)]),
        header=ui.panel_header("Mail", [ui.icon_button("plus", on_new, size="xs")], icon="mail"),
        width=220, side="left",
    ),
    pz.container(ui.muted("Content"), center=True, width="fill", height="fill"),
], height="fill")
```

## Variantes

:::note[Sobre estas capturas]
Cada captura la graba pyzed mismo, fuera de pantalla a 2x, en One Dark o One Light según el tema de este sitio, y recortada al componente para que se vea a su tamaño real. El puntero pasa por encima, pulsa o escribe en él; un componente que no reacciona al puntero recorre algunos temas. Con movimiento reducido ves el primer fotograma. Abre **Código** bajo una captura para ver el fragmento que la dibuja; los nombres libres como `on_save` son tus propios callbacks.
:::

### Lado

```python
pz.row([ui.panel(ui.list_item("Inbox", icon="inbox", inset=True), header=ui.panel_header("Mail"),
                 width=160, side="left"), pz.container(width="fill")], height="fill")
```

```python
pz.row([pz.container(width="fill"), ui.panel(ui.muted("Properties"), header=ui.panel_header("Inspector"),
                                          width=160, side="right")], height="fill")
```

```python
pz.column([pz.container(height="fill"), ui.panel(ui.terminal("$ ls"), header=ui.panel_header("Terminal"),
                                             height=100, side="bottom")], width="fill")
```

## Eventos

Panel tiene **1 evento propios**, en la tabla de abajo. Como todo widget, también tiene los **18 eventos comunes** (`click`, `double_click`, `right_click`, `mouse_enter`, `drag`, `key_down`, `resize`…), que se conectan con `.on(...)`: mira [Eventos](https://albakore.github.io/pyzed/es/guides/events/) y [Eventos de cada componente](https://albakore.github.io/pyzed/es/library/events/).

| Evento | El handler recibe | Cuándo |
| --- | --- | --- |
| `on_resize` | `(size)` | Se llama con el nuevo tamaño al terminar de arrastrar. |

**El handler recibe** es lo que Pyzed le pasa a tu función: `()` es nada. Cualquier handler también puede ser un mensaje (un valor que no se puede llamar), que va a `update()`.

### Manejar los eventos

Los mismos eventos escritos de tres formas. **Imperativa**: métodos de la app que cambian `self`. **Declarativa**: los handlers producen mensajes y un único `update()` decide. **Funcional**: una función pura dibuja un estado inmutable y pide cambios con `set_state(...)`. Mira [Imperativo, declarativo y funcional](https://albakore.github.io/pyzed/es/guides/code-styles/).

**Imperativo:**

```python
class Mail(pz.App):
    def __init__(self):
        self.width = 220

    def view(self):
        return pz.row([
            ui.panel(ui.muted("Inbox"), header=ui.panel_header("Mail"), width=self.width,
                     on_resize=lambda size: setattr(self, "width", size)),   # when the drag ends
            main_view(),
        ], height="fill")
```

**Declarativo:**

```python
from dataclasses import dataclass

@dataclass
class Width:
    size: float

class Mail(pz.App):
    width = 220

    def update(self, message):
        match message:
            case Width(size):
                self.width = size

    def view(self):
        return pz.row([ui.panel(ui.muted("Inbox"), width=self.width, on_resize=Width), main_view()],
                      height="fill")
```

**Funcional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    width: float = 220

def view(state, set_state):
    return pz.row([ui.panel(ui.muted("Inbox"), width=state.width, on_resize=lambda s: set_state(width=s)),
                   main_view()], height="fill")
```

## Propiedades y API

### `ui.panel`

```python
panel(
    content,
    *,
    header=None,
    width=None,
    height=None,
    side='left',
    resizable=True,
    on_resize=None,
    min_size=120,
    theme=None,
)
```

Un panel acoplable. `side` decide en qué borde va la línea; con un `width` numérico (`height` para el inferior) ese borde se arrastra para cambiar su tamaño.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `content` | *obligatorio* | Contenido: un `Widget`, un texto o un número (se convierte en texto). |
| `header` | `None` | Cabecera (`ui.panel_header`). |
| `width` | `None` | Ancho: píxeles, `"fill"`, `"shrink"` o `"fill:N"` (proporción). |
| `height` | `None` | Alto: píxeles, `"fill"`, `"shrink"` o `"fill:N"` (proporción). |
| `side` | `"left"` | `"left"`, `"right"` o `"bottom"`. |
| `resizable` | `True` | `False` mantiene el tamaño fijo. |
| `min_size` | `120` | Tamaño mínimo al redimensionar. |
| `theme` | `None` | Tema a usar en lugar del actual (`pyzed.theme.current()`). |

Eventos: `on_resize` ([eventos](#eventos)).

[Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#panel)

## Relacionados

- [Cabecera de panel](https://albakore.github.io/pyzed/es/library/panel-header/): Icono, título y acciones encima de un dock.
- [Espacio de trabajo](https://albakore.github.io/pyzed/es/library/workspace/): La disposición de una ventana estilo editor: barra de título, docks, centro y barra de estado.
- [División](https://albakore.github.io/pyzed/es/library/split/): Dos paneles con un divisor que se arrastra.
