# Panel dropdowns

****

Our action dropdowns for pages, files and users are all loaded on request. This way, we can load and evaluate permissions individually from the API and then disable items in the dropdowns that should not be accessible.

As part of your <a href="https://getkirby.com/docs/reference/plugins/extensions/panel-areas">Panel area extension</a>, you can also define custom dropdowns easily on the backend and use them in your Panel frontend code with a simple single call.

```html
<k-button @click="$refs.options.toggle()">Options</k-button>
<k-dropdown-content
  ref="options"
  :options="$dropdown('pages/projects+project-a')"
/>
```

The backend code for this is very straightforward as well and is defined as part of our areas

```php "Site area"
return [
    'label' => 'Site',
    ...
    'dialogs' => ...
    'views' => ...
    'dropdowns' => [
        'pages/(:any)' => function (string $id) {
            $page = Find::page($id);

            return [
                [
                    'text' => 'Open',
                    'icon' => 'preview',
                    'link' => $page->previewUrl(),
                ],
                ...
                [
                    'text'   => 'Delete',
                    'icon'   => 'trash',
                    'dialog' => 'pages/' . $id . '/delete'
                ]
            ];
        }
    ]
];
```

## Option settings

The dropdown definition returns an array of dropdown options. Each option can define a set of parameters to control how the option is displayed and what happens on click.

| Parameter | Type | Description |
| - | - | - |
| `click` | `string` | The name of the event that will be triggered on click |
| `dialog` | `string|array` | Either a single path to a dialog or dialog settings |
| `disabled` | `bool` | Enable/disable the item |
| `icon` | `string` | The name of the option icon |
| `link` | `string` | An optional url/path to create a link instead of a button |
| `target` | `string` | A link target (i.e. _blank) |
| `text` | `string` | The label for the option |

## Custom dropdowns

Of course, you can create your own dropdowns for your plugins as part of your <a href="https://getkirby.com/docs/reference/plugins/extensions/panel-areas">Panel area extension</a>:

```php
Kirby::plugin('your-plugin/todos', [
    'areas' => [
        'todos' => function ($kirby) {
            return [
                ...
                'dropdowns' => [
                    'todos/(:any)' => function (string $id) {
                        // find the $todo here. (i.e. from a database)
                        return [
                            [
                                'text'   => 'Edit',
                                'dialog' => 'todos/' . $id . '/edit',
                                'icon'   => 'edit'
                            ],
                            [
                                'text'   => 'Duplicate',
                                'dialog' => 'todos/' . $id . '/duplicate',
                                'icon'   => 'copy'
                            ],
                            [
                                'text'   => 'Delete',
                                'dialog' => 'todos/' . $id . '/delete',
                                'icon'   => 'trash'
                            ]
                        ];
                    }
                ]
            ];
        }
    ]
]);
```

Your dropdown options can then be loaded in your Vue code like this:

```html
<k-button icon="cog" @click="$refs.options.toggle()">Options</k-button>
<k-dropdown-content ref="options" :options="$dropdown('todos/the-todo-id')" />
```

## Extending dropdowns

Pages, files and users have dynamic option dropdowns. Those dropdowns show all the available options like changing titles, sorting pages, deleting stuff, etc.

Those dropdowns can be extended or modified to add additional options, remove options or simply change what's normally shown.

```php
<?php

Kirby::plugin('example/dropdown', [
  'areas' => [
    'site' => function ($kirby) {
      return [
        'dropdowns' => [
          'page' => function (string $id) {

            // find the right page for the dropdown
            $page = Find::page($id);

            // load the core dropdown definition
            $dropdown = $page->panel()->dropdown();

            // append a separator
            $dropdown[] = '-';

            // append a new option
            $dropdown[] = [
              'icon'   => 'share',
              'text'   => 'Publish on Netlify',
              'dialog' => 'publish'
            ];

            return $dropdown;
          }
        ]
      ];
    },
  ]
]);
```

#### Listen for dropdown event

When you need to react to your added dropdown entry, there is no direct way that you could listen for the event on the Vue dropdown component, since you don't have access to it. Instead, you can pass the `click` handler in the following way:

```php
$dropdown[] = [
	'icon'  => 'share',
	'text'  => 'Publish on Netlify',
	'click' => [
		'global'  => 'myEvent',
		'payload' => [...]
	]
];
```

With this you can listen for your event globally:

```js
this.$events.on("myEvent", (payload) => {...});
```

### Reusing core code

When you plan to extend a dropdown, you might want to fall back to Kirby's core behaviour in some cases. This can be done by loading the core code:

```php
<?php

Kirby::plugin('example/dropdown', [
  'areas' => [
    'site' => function ($kirby) {
      return [
        'dropdowns' => [
          'page' => function (string $id) use ($kirby) {

            // find the right page for the dropdown
            $page = Find::page($id);

            if ($page->id() === 'blog') {
                // return a custom dropdown
            }

            return $kirby->core()->area('site')['dropdowns']['page']['options']($id);
          }
        ]
      ];
    },
  ]
]);
```

The core models (page, user and file) all have a separate `$model->panel()->dropdown()` method for their own dropdown. While the code above is the correct way to load core code for any part of an area, you can simplify this for dropdowns by reusing the dropdown method.

```php
<?php

Kirby::plugin('example/dropdown', [
  'areas' => [
    'site' => function ($kirby) {
      return [
        'dropdowns' => [
          'page' => function (string $id) {
            // find the right page for the dropdown
            $page = Find::page($id);

            if ($page->id() === 'blog') {
                // return a custom dropdown
            }

            return $page->panel()->dropdown();
          }
        ]
      ];
    },
  ]
]);
```

## Core dropdowns

Area | Dropdown name
- | -
`site` | `page`
`site` | `page.file`
`site` | `site.file`
`users` | `user`
`users` | `user.file`