# Panel drawers

****

As part of your <a href="https://getkirby.com/docs/reference/plugins/extensions/panel-areas">Panel area extension</a>, you can also define custom drawers for the Panel as well as extend or modify the Panel's default drawers.

## Supported UI components

All reuse the same drawer components:

| Component name | Usage |
| --- | --- |
| <a href="https://lab.getkirby.com/public/lab/docs/k-form-drawer">`k-form-drawer`</a> | For drawers with form fields |
| <a href="https://lab.getkirby.com/public/lab/docs/k-text-drawer">`k-text-drawer`</a> | For drawers with a custom text message |

## Drawer definition

Drawers are defined as a part of areas:

```php
Kirby::plugin('yourname/todos', [
  'areas' => [
    'todos' => function ($kirby) {
      return [
        // ... other code for custom Panel area
        'drawers' => [

          // the key of the drawer defines its routing pattern
          'todos/create' => [
            // drawer callback functions
            'load'   => function () {},
            'submit' => function () {}
          ]
        ]
      ];
    }
  ]
]);
```

### `load` callback

The `load` function is called when the drawer is opened. It needs to return an array that specifies the UI component (see above) to be used for the drawer as well as all props that should be passed to the UI component, e.g. field definitions and values for a form drawer.

```php
Kirby::plugin('yourname/todos', [
  'areas' => [
    'todos' => function ($kirby) {
      return [
        'drawers' => [
          'todos/create' => [
            // the load event is creating a GET route at
            // `/panel/drawers/{pattern}`;
            // it returns the setup for the drawer, including
            // used component, buttons, props, etc.
            'load' => function () {
              return [
                // what drawer component to use
                'component' => 'k-form-drawer',
                'props' => [
                  // field definition for the form drawer
                  'fields' => [ ... ],
                  // the prefilled model data
                  'value' => [ ... ]
                ]
              ];
            },
            // ...
          ]
        ]
      ];
    }
  ]
]);
```

### `submit` callback

The `submit` function is called once the drawer is submitted and defines the actions triggered by the event but also the response the Panel will receive.

```php
Kirby::plugin('yourname/todos', [
  'areas' => [
    'todos' => function ($kirby) {
      return [
        'drawers' => [
          'todos/create' => [
            // ...

            // the submit event is creating a POST route at
            // `/panel/drawers/{pattern}`;
            // the submit button of the drawer is automatically
            // wired to fire the POST request with the form
            // data or whatever data the drawer provides
            'submit' => function () {
              // create todo
              return true;
            }
          ]
        ]
      ];
    }
  ]
]);
```

The drawer's `submit` callback has multiple ways to interact with the component presented in the Panel via its response:

`return void|null|false`
Returning nothing or `false` is interpreted as a 404. It suggests that the model could not be found.

`return true`
Returning true is interpreted as a success and will automatically close the drawer.

`return [ ... ]`
By returning an array, you gain more control of what happens when the drawer closes by passing data to the event:

```php
return [
  'event' => 'todo.create',
  'data'  => [
    // some data for the event
  ],
];
```

`throw new Exception`
Any exception is interpreted as an error and will show the error message box in the drawer containing the exception message

`Panel::go()`
You can redirect the Panel to a different location after submitting the drawer by calling:

```php
Panel::go('some/path');
```

<since v="5.1.0">
### Controller classes

Instead of defining the drawer directly as an array with `load` and `submit` keys, you can pass a controller class name or a closure that returns an object with `load` and `submit` methods. If the named class defines a static `::for()` method, Kirby will call it to create the instance.

```php
Kirby::plugin('yourname/todos', [
  'areas' => [
    'todos' => function () {
      return [
        'drawers' => [
          'todos/create' => [
            'controller' => TodoCreateDrawerController::class
          ],
          'todos/edit' => [
            'controller' => fn () => new TodoEditDrawerController()
          ]
        ]
      ];
    }
  ]
]);
```
</since>