# Icon picker

> Pick one of the ~2000 Lucide icons from a searchable grid. A native Pyzed component for Python desktop GUIs, with a live preview, code examples and its API.

Source: https://albakore.github.io/pyzed/library/icon-picker/

:::tip[In plain words]
A searchable grid of little pictures to choose an icon from.
:::

`ui.IconPicker` is a component with a search box, a category drop-down and a grid of every bundled Lucide icon. The search matches names and tags ("person" finds `user`), Enter picks the first match and `on_change` receives the icon's name in `event.value`. `ui.icon_picker_dialog` puts it in a dialog that picks on a click, and `ui.icon_grid` is the bare grid, which only builds the rows in view.

`ui.IconPicker` · Category: [Forms](https://albakore.github.io/pyzed/library/#forms) · [Full reference →](https://albakore.github.io/pyzed/reference/ui/#iconpicker)

**Code:**

```python
ui.IconPicker(value="rocket", columns=10, height=200, clearable=True, on_change=on_change)
```

:::note[New]
This component was added recently. Tell us how it works for you in the [issue tracker](https://github.com/albakore/pyzed/issues).
:::

## When to use

- To let users choose an icon for a folder, a tag, a shortcut or a toolbar button.
- Show the current icon as a button and open `icon_picker_dialog` in a [Dialog layer](https://albakore.github.io/pyzed/library/dialog-layer/) when it is pressed.

## Usage

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

class Shortcuts(pz.App):
    def __init__(self):
        self.icon = "rocket"
        self.picking = False

    def pick(self, name):
        self.icon, self.picking = name or "circle-dashed", False

    def view(self):
        page = ui.button("Change icon", lambda: setattr(self, "picking", True), icon=self.icon)
        dialog = ui.icon_picker_dialog(self.icon, self.pick, on_close=lambda: setattr(self, "picking", False))
        return ui.dialog_layer(page, dialog if self.picking else None,
                               on_dismiss=lambda: setattr(self, "picking", False))
```

## Variants

:::note[About these captures]
Each capture is recorded by pyzed itself, off-screen at 2x, in One Dark or One Light to match this site's theme, and cropped to the component so it shows at its real size. The pointer hovers, presses or types into it; a component that does not react to the pointer cycles through a few themes. With reduced motion you see the first frame. Open **Code** under a capture to see the snippet that draws it; free names such as `on_save` stand for your own callbacks.
:::

### Picker

```python
ui.IconPicker(value="rocket", columns=8, height=180, on_change=on_change)
```

```python
ui.IconPicker(value="heart", columns=8, height=180, clearable=True, on_change=on_change)
```

### Building blocks

```python
ui.icon_grid(pz.icons.search("arrow")[:24], on_pick, selected="arrow-right", columns=8, height=110)
```

```python
ui.icon_picker_dialog("rocket", on_pick, on_close=on_close, columns=8)
```

## Events

Icon picker has **3 events of its own**, listed below. Like every widget it also has the **18 common events** (`click`, `double_click`, `right_click`, `mouse_enter`, `drag`, `key_down`, `resize`…), attached with `.on(...)`: see [Events](https://albakore.github.io/pyzed/guides/events/) and [Events of every component](https://albakore.github.io/pyzed/library/events/).

It is a `pz.Component`, so it also raises `on_mount` and `on_unmount`, and its handlers get a `pz.Event` whose `value` holds the data.

| Event | Of | Handler gets | When |
| --- | --- | --- | --- |
| `on_change` | `ui.IconPicker` | `(event)` | Receives `event.value`. |
| `on_pick` | `ui.icon_picker_dialog`, `ui.icon_grid` | `(name)` | Called with the clicked icon's name (`""` when cleared). |
| `on_close` | `ui.icon_picker_dialog` | `()` | The close button. |

**Handler gets** is what Pyzed passes to your callable: `()` means nothing. Any handler can also be a message (a value that is not callable), which goes to `update()`.

### Handling the events

The same events written three ways. **Imperative**: methods of the app change `self`. **Declarative**: the handlers produce messages and one `update()` decides. **Functional**: a pure function draws an immutable state and asks for changes with `set_state(...)`. See [Imperative, declarative and functional](https://albakore.github.io/pyzed/guides/code-styles/).

**Imperative:**

```python
class Shortcut(pz.App):
    def __init__(self):
        self.icon = "rocket"
        self.picking = False

    def pick(self, name):                # on_pick: the icon's name ("" when cleared)
        self.icon, self.picking = name or "circle-dashed", False

    def view(self):
        page = ui.button("Change icon", lambda: setattr(self, "picking", True), icon=self.icon)
        dialog = ui.icon_picker_dialog(self.icon, self.pick, on_close=lambda: setattr(self, "picking", False))
        return ui.dialog_layer(page, dialog if self.picking else None,
                               on_dismiss=lambda: setattr(self, "picking", False))
```

**Declarative:**

```python
from dataclasses import dataclass

@dataclass
class Icon:
    name: str

class Shortcut(pz.App):
    icon = "rocket"

    def update(self, message):
        match message:
            case Icon(name):
                self.icon = name or "circle-dashed"

    def view(self):
        # IconPicker is a pz.Component: its handler gets a pz.Event
        return ui.IconPicker(value=self.icon, height=200, on_change=lambda e: Icon(e.value))
```

**Functional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    icon: str = "rocket"

def view(state, set_state):
    return pz.column([
        ui.icon_grid(["rocket", "star", "heart", "bell"], lambda name: set_state(icon=name),
                     selected=state.icon, columns=4, height=60),
        ui.button("Launch", None, icon=state.icon),
    ], spacing=8)
```

## Properties and API

### `ui.IconPicker`

```python
class IconPicker
```

A component that picks a Lucide icon: a search box (names and tags), a category drop-down and a grid that only builds the rows in view. Enter picks the first match. `on_change` gets the icon's name (`""` when cleared); pass it back as `value`. See the [Icon picker](https://albakore.github.io/pyzed/library/icon-picker/) page.

| Property | Default | Description |
| --- | --- | --- |
| `value` | `""` | The picked icon's name. |
| `columns` | `8` | Icons per row. |
| `height` | `288` | Height of the grid. |
| `clearable` | `False` | Shows a button that clears the icon. |
| `autofocus` | `False` | Focuses the search box when it appears. |

Events: `on_change` ([events](#events)).

[Full reference →](https://albakore.github.io/pyzed/reference/ui/#iconpicker)

### `ui.icon_picker_dialog`

```python
icon_picker_dialog(
    value,
    on_pick,
    *,
    on_close=None,
    title=None,
    columns=10,
    clearable=True,
    key='icon-picker',
    theme=None,
)
```

A dialog with an `IconPicker` that picks on a click; use it as the dialog of `ui.dialog_layer`. The search box gets the focus.

| Property | Default | Description |
| --- | --- | --- |
| `value` | *required* | The current icon. |
| `title` | `None` | Default: "Choose an icon", translated. |
| `columns` | `10` | Icons per row. |
| `clearable` | `True` | Shows the "No icon" button. |
| `key` | `"icon-picker"` | Component key, for several pickers in one view. |
| `theme` | `None` | Theme. |

Events: `on_pick`, `on_close` ([events](#events)).

[Full reference →](https://albakore.github.io/pyzed/reference/ui/#icon_picker_dialog)

### `ui.icon_grid`

```python
icon_grid(
    names,
    on_pick,
    *,
    selected=None,
    columns=8,
    cell=34,
    height=288,
    id=None,
    theme=None,
)
```

The bare grid of icons, virtualized: only the rows in view are built, so thousands of icons cost the same as a few.

| Property | Default | Description |
| --- | --- | --- |
| `names` | *required* | Icon names, in order. |
| `selected` | `None` | The highlighted name. |
| `columns` | `8` | Icons per row. |
| `cell` | `34` | Side of each cell in pixels. |
| `height` | `288` | Height of the grid. |
| `id` | `None` | Id of the scrollable, for `Command.scroll_to`. |
| `theme` | `None` | Theme. |

Events: `on_pick` ([events](#events)).

[Full reference →](https://albakore.github.io/pyzed/reference/ui/#icon_grid)

### `pz.icons.search`

```python
search(query, among=None)
```

Icons matching a search by name and tag, best first: exact names, then names that start with the query, names with every word and icons found by their tags (`search("person")` finds `user`).

| Property | Default | Description |
| --- | --- | --- |
| `query` | *required* | Words that must all appear in the name or the tags. |
| `among` | `None` | Only search these names (default: every icon). |

[Full reference →](https://albakore.github.io/pyzed/reference/icons/#search)

### `pz.icons.category`

```python
category(key, among=None)
```

The icons of a category of `CATEGORIES`, sorted. An icon can be in several.

| Property | Default | Description |
| --- | --- | --- |
| `key` | *required* | A key of `CATEGORIES` (`"arrows"`, `"files"`, `"people"`...). |
| `among` | `None` | Only look at these names. |

[Full reference →](https://albakore.github.io/pyzed/reference/icons/#category)

## Related

- [Icon](https://albakore.github.io/pyzed/library/icon/): Lucide icons by name, and SVG images.
- [Dialog layer](https://albakore.github.io/pyzed/library/dialog-layer/): Centers a dialog over your view with a dimmed backdrop.
- [Color picker](https://albakore.github.io/pyzed/library/color-picker/): Pick a color, a gradient or a masked fill; swatches show them.
