# Tool.view
URL: https://lsd.tools/docs/api-tool-view
Updated: 2026-07-18

## Parameters

| name | type | default | description |
|---|---|---|---|
| `view_id` | `str` | — | the unique view id |
| `title` | `str` | `None` | the view tab/panel title (defaults from `view_id`) |
| `location` | `str` | `"editor"` | where it mounts: `"editor"` (a tab), `"sidebar"` (a docked panel), or `"overlay"` (a HUD over the 3D viewer) |
| `icon` | `str` | `None` | a symbolic icon name for the tab |
| `menu` | `str` | `None` | a menu id under which to expose an open-view item |
| `dock` | `str` | `None` | for `location="overlay"`, where the HUD docks over the viewer |
| `view_kind` | `str` | `None` | for `location="overlay"`, the 3D viewer kind the HUD sits over |

## Example

```python
@tool.view("grades", "Grades")
def grades_view(ctx):
    from lsdtools import views
    return views.chart(kind="histogram", title="Grades")
```

## Notes

The factory is `(ctx)` or `(ctx, entity=None) -> View` — return a `table`, `chart`, or `flowchart`
from `lsdtools.views`, or a custom `View` subclass. `location` places it: `"editor"` (a tab),
`"sidebar"` (a docked panel), or `"overlay"` (a HUD over the 3D `view_kind` viewer at `dock`). The
desktop mounts it and draws its shell; a headless host uses the View's `to_text()` / `to_image()`.
The same `View` also runs standalone through its own `show()`.

Returning a raw toolkit widget is a mount error — a package's only path to GTK is a custom view's
shell, registered separately via `from lsdtools.views import set_view_shell`. Sugar over
[`contribute`](/docs/api-tool-contribute) with a `ViewContribution`.

## See also

**API:** [contribute](/docs/api-tool-contribute) · [Data views](/docs/ui-widgets) · [Advanced](/docs/api-advanced)

**Guides:** [Data views](/docs/ui-widgets) · [Custom views](/docs/ui-custom-views) · [Contributing UI](/docs/tools-panels-overlays-views)
