Widgets are cards that hold some information or any content you want to display.

Creating Widgets

You can generate new action classes by calling the root:widget artisan command:

php artisan root:widget PostCount

Registering Widgets

You can register actions in resources and extracts, by using the widgets method.

use App\Root\Widgets\PostCount;
use Cone\Root\Http\Requests\RootRequest;

/**
 * Define the widgets for the resource.
 *
 * @param  \Cone\Root\Http\Requests\RootRequest  $request
 * @return array
 */
public function widgets(RootRequest $request): array
{
    return array_merge(parent::widgets($request), [
        PostCount::make(),
    ]);
}

Alternatively, you can use withWidgets method on an object that resovles widgets. It can be useful when you just want to hook into the object for some reason.

use App\Root\Widgets\PostCount;
use Cone\Root\Support\Collections\Widgets;
use Cone\Root\Http\Requests\RootRequest;

$resource->withWidgets(static function (RootRequest $request, Widgets $widgets): Widgets {
    return $widgets->merge([
        PostCount::make(),
    ]);
});

You can also pass an array instead of a Closure. In that case the array will be merged into the collection.

Configuration

Authorization

You may allow or disallow interaction with widgets. To do so, you can call the authorize method on the widget instance:

$widget->authorize(static function (RootRequest $request): bool {
    return $request->user()->can('viewPostCount');
});

Visibility

You may show or hide widgets based on the current resource view. For example, some widgets might be visible on the index page, while others should be hidden. You can easily customize the action visibility logic using the visibleOn and hiddenOn methods:

$widget->visibleOn(static function (RootRequest $request): bool {
    return $request->user()->can('viewPostCount');
});

$widget->hiddenOn(static function (RootRequest $request): bool {
    return $request->user()->cannot('viewPostCount');
});

Also, you can use the built-in methods as well:

$widget->visibleOnIndex();
$widget->visibleOnShow();

$widget->hiddenOnIndex();
$widget->hiddenOnShow();

Blade Templates

A widget class must have a valid template property, that holds a real blade template:

use Cone\Root\Widgets\Widget;

class PostCount extends Widget
{
    /**
     * The Blade template.
     *
     * @var string
     */
    protected string $template = 'widgets.post-count;
}

Widget Data

You can customize the data passed to the blade template by using the data method:

use App\Models\Post;
use Cone\Root\Http\Requests\RootRequest;
use Cone\Root\Widgets\Widget;

class PostCount extends Widget
{
    /**
     * Get the data.
     *
     * @param  \Cone\Root\Http\Requests\RootRequest  $request
     * @return array
     */
    public function data(RootRequest $request): array
    {
        return [
            'count' => Post::query()->count(),
        ];
    }
}

Alternatively, you can use with method on a widget. It can be useful when you just want to hook into the object for some reason.

use App\Models\Post;
use Cone\Root\Http\Requests\RootRequest;

$widget->with(static function (RootRequest $request): array {
    return [
        'published_count' => Post::query()->published()->count(),
    ];
});

You can also pass an array instead of a Closure.

Custom Components

By default, widget use the Widget component, however you can use any component you want. You may also register your own custom component as well:

document.addEventListener('root:booting', ({ detail }) => {
    detail.app.component('CustomWidget', require('./Components/CustomWidget').defaul);
});
use Cone\Root\Widgets\Widget;

class PostCount extends Widget
{
    /**
     * The Vue component.
     *
     * @var string|null
     */
    protected string $component = 'CustomWidget';
}

Async Widgets

In some scenarios, you may want your widget to be asynchronously loaded. For example, when the rendered template generates a huge chunk of data, you may want to load the component in another HTTP request. To do so, call the ─ůsyc method on the widget instance:

PostCount::make()->async();

Please note, all the routes for the asnyc widgets will be registered automatically.