Components

CardsBuilder

Basics

With CardsBuilder, you can display a list of items in the form of cards.
You can also use CardsBuilder on your own pages or even outside of MoonShine.

use MoonShine\UI\Components\CardsBuilder;
 
CardsBuilder::make(iterable $items = [], FieldsContract|iterable $fields = [])
<x-moonshine::layout.grid>
<x-moonshine::layout.column colSpan="4" adaptiveColSpan="12">
<x-moonshine::card
url="#"
thumbnail="/images/image_1.jpg"
:title="fake()->sentence(3)"
:subtitle="date('d.m.Y')"
:values="['ID' => 1, 'Author' => fake()->name()]"
>
<x-slot:header>
<x-moonshine::badge color="green">new</x-moonshine::badge>
</x-slot:header>
 
{{ fake()->text() }}
 
<x-slot:actions>
<x-moonshine::link-button href="#">Read more</x-moonshine::link-button>
</x-slot:actions>
</x-moonshine::card>
</x-moonshine::layout.column>
</x-moonshine::layout.grid>
  • $fields - fields,
  • $items - field values.

Basic Usage

Example of using CardsBuilder:

CardsBuilder::make(
[
['id' => 1, 'title' => 'Title 1'],
['id' => 2, 'title' => 'Title 2'],
],
[
ID::make(),
Text::make('title')
]
)

Items and fields for CardsBuilder can be specified using the corresponding methods.

Basic Methods

Items and Fields

The items() method allows you to pass data to CardsBuilder to fill the cards.

items(iterable $items = [])

The fields() method allows you to pass a list of fields to CardsBuilder for building the card.

fields(FieldsContract|Closure|iterable $fields)
CardsBuilder::make()
->fields([Text::make('Text')])
->items([['text' => 'Value']])

Paginator

The paginator method sets the paginator. You need to pass an object that implements the MoonShine\Contracts\Core\Paginator\PaginatorContract interface:

If you need to specify a paginator for QueryBuilder, you can use the built-in ModelCaster, as in the example below:

->paginator(
(new ModelCaster(Article::class))
->paginatorCast(
Article::query()->paginate()
)
)

The paginator can also be specified through a method or the items parameter.

View Methods

Content

The content() methods are used to add arbitrary content to the card.

content(Closure|string $value)
CardsBuilder::make(
fields: [Text::make('Text')],
items: Article::paginate()
)
->content('Custom content')

Title

The title() method allows you to set the title of the card.

title(Closure|string $value)
  • $value - column or a closure that returns the title.
CardsBuilder::make(
fields: [Text::make('Text')],
items: Article::paginate()
)
->title('title')

URL

The url() method allows you to set a link for the title.

url(Closure|string $value)
CardsBuilder::make(
fields: [Text::make('Text')],
items: Article::paginate()
)
->title('title')
->url(fn($data) => $this->getFormPageUrl($data))

Subtitle

The subtitle() method allows you to set the subtitle of the card.

subtitle(Closure|string $value)
  • $value - column or a closure that returns the subtitle.
CardsBuilder::make(
items: Article::paginate()
)
->fields([Text::make('Text')])
->title('title')
->subtitle(static fn() => 'Subtitle')

Thumbnail

To add an image to the card, you can use the thumbnail() method.
As an argument, the method accepts a value of the column field or a closure that returns the url of the image.

thumbnail(Closure|string $value)
CardsBuilder::make(
items: Article::paginate()
)
->fields([Text::make('Text')])
->thumbnail('thumbnail')
// or by url
// ->thumbnail(fn() => 'https://example.com/image.png')

Overlay Mode

The overlay mode allows you to place the title and subtitles on top of the card image.
This mode is activated using the method overlay().

CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Text::make('Text')])
->cast(new ModelCaster(Article::class))
->thumbnail('thumbnail')
->header(static fn() => Badge::make('new', 'success'))
->title('title')
->subtitle(static fn() => 'Subtitle')
->overlay()

Header

The header() method allows you to set a header for the cards.

Works only when thumbnail is present and in overlay mode

header(Closure|string $value)
  • $value - column or a closure that returns html code.
CardsBuilder::make()
->items(Article::paginate())
->thumbnail('image')
->overlay()
->fields([Text::make('Text')])
->header(static fn() => Badge::make('new', 'success'))
// or by column
// ->header('title')

Buttons

To add buttons based on ActionButton, use the buttons() method.

CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->cast(new ModelCaster(Article::class))
->buttons([
ActionButton::make('Delete', route('name.delete')),
ActionButton::make('Edit', route('name.edit'))->showInDropdown(),
ActionButton::make('Go to Home', route('home'))->blank()->canSee(fn($data) => $data->active)
])

Columns

The columnSpan() method allows you to set the width of the cards in Grid.

columnSpan(
int $columnSpan,
int $adaptiveColumnSpan = 12
)
  • $columnSpan - value for the desktop version,
  • $adaptiveColumnSpan - value for the mobile version.
CardsBuilder::make(
fields: [Text::make('Text')],
items: Article::paginate()
)
->columnSpan(3)

The MoonShine admin panel uses a 12-column grid.

Custom Component

The CardsBuilder component allows you to override the component for building the item list.
To do this, use the customComponent() method.

CardsBuilder::make(
fields: [Text::make('Text')],
items: Article::paginate()
)
->customComponent(function (Article $article, int $index, CardsBuilder $builder) {
return Badge::make($index + 1 . "." . $article->title, 'green');
})

Async Mode

If you need to fetch data asynchronously (for example, during pagination), use the async() method.

The async method should be after the name method

->async(
Closure|string|null $url = null,
string|array|null $events = null,
?AsyncCallback $callback = null,
)
  • $url - URL for the asynchronous request (the response must return TableBuilder),
  • $events - events that will be triggered after a successful response,
  • $callback - JS callback that can be added as a wrapper for the response.
CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->name('my-cards')
->async()

After a successful request, you can trigger events by adding the events parameter.

CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->name('crud')
->async(events: [AlpineJs::event(JsEvent::CARDS_UPDATED, 'crud')])

For more information about JS events, refer to the Events section.

To trigger the event, you must specify a unique component name!

Type Casting

The cast method is used to cast values to a specific type.
Because by default, fields work with primitive types:

use MoonShine\Laravel\TypeCasts\ModelCaster;
 
CardsBuilder::make()
->cast(new ModelCaster(User::class))

In this example, we cast the data to the format of the User model using ModelCaster.

For more detailed information, refer to the TypeCasts section.

Usage in Blade

Basics

<x-moonshine::layout.grid>
<x-moonshine::layout.column colSpan="4" adaptiveColSpan="12">
<x-moonshine::card
url="#"
thumbnail="/images/image_1.jpg"
:title="fake()->sentence(3)"
:subtitle="date('d.m.Y')"
:values="['ID' => 1, 'Author' => fake()->name()]"
>
<x-slot:header>
<x-moonshine::badge color="green">new</x-moonshine::badge>
</x-slot:header>
 
{{ fake()->text() }}
 
<x-slot:actions>
<x-moonshine::link-button href="#">Read more</x-moonshine::link-button>
</x-slot:actions>
</x-moonshine::card>
</x-moonshine::layout.column>
</x-moonshine::layout.grid>

Implemented based on several components, more details in the sections: Card, Grid, Column.