Advanced

CardsBuilder

Extends MoonShineComponent

  • has the same features

Basics

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

CardsBuilder::make( Fields|array $fields = [], protected iterable $items = [] )
CardsBuilder::make(
Fields|array $fields = [],
protected iterable $items = []
)
  • $fields - fields,
  • $items - field values.
CardsBuilder::make( [ ['id' => 1, 'title' => 'Title 1'], ['id' => 2, 'title' => 'Title 2'], ], [ ID::make(), Text::make('title') ] )
CardsBuilder::make(
[
['id' => 1, 'title' => 'Title 1'],
['id' => 2, 'title' => 'Title 2'],
],
[
ID::make(),
Text::make('title')
]
)

Elements and fields for CardsBuilder can be specified using the appropriate methods.

Items and fields

The items() method allows you to pass data to CardsBuilder for filling cards.

items(iterable $items = [])
items(iterable $items = [])

The fields() method allows you to pass CardsBuilder a list of fields to build a card.

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

The correspondence of data with fields is carried out through the value column fields!

Casting

The cast() method is used to cast table values to a specific type.
Since by default fields work with primitive types:

use MoonShine\TypeCasts\ModelCast; CardsBuilder::make(items: User::paginate()) ->fields([Text::make('Email')]) ->cast(ModelCast::make(User::class))
use MoonShine\TypeCasts\ModelCast;
CardsBuilder::make(items: User::paginate())
->fields([Text::make('Email')])
->cast(ModelCast::make(User::class))

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

For more detailed information, please refer to the section [TypeCasts](/docs/2.x/advanced/type_casts" class="text-purple underline" link="/docs/2.x/advanced/type_casts)

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

header(Closure|string $value)
header(Closure|string $value)
  • $value - column or closure returning html code.
CardsBuilder::make( items: Article::paginate() ) ->fields([Text::make('Text')]) ->header(static fn() => Badge::make('new', 'success'))
CardsBuilder::make(
items: Article::paginate()
)
->fields([Text::make('Text')])
->header(static fn() => Badge::make('new', 'success'))

Content

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

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

Link

Using the url() method, you can set a link to the header.

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

Subtitle

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

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

Thumbnail

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

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

Buttons

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

CardsBuilder::make() ->items(Article::paginate()) ->fields([ID::make(), Switcher::make('Active')]) ->cast(ModelCast::make(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) ])
CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->cast(ModelCast::make(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)
])

Overlay mode

The overlay mode allows you to place the header and headings on top of the card image.
This mode is activated by the overlay() method of the same name.

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

Paginator

The paginator() method for the table to work with pagination.

$paginator = Article::paginate(); CardsBuilder::make() ->fields([Text::make('Text')]) ->items($paginator->items()) ->paginator($paginator)
$paginator = Article::paginate();
CardsBuilder::make()
->fields([Text::make('Text')])
->items($paginator->items())
->paginator($paginator)

Or directly pass the paginator:

CardsBuilder::make( items: Article::paginate() ) ->fields([Text::make('Text')])
CardsBuilder::make(
items: Article::paginate()
)
->fields([Text::make('Text')])

Asynchronous mode

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

async( ?string $asyncUrl = null, string|array|null $asyncEvents = null, ?string $asyncCallback = null )
async(
?string $asyncUrl = null,
string|array|null $asyncEvents = null,
?string $asyncCallback = null
)
  • asyncUrl - request url (by default, the request is sent to the current url),
  • asyncEvents - events called after a successful request,
  • asyncCallback - js callback function after receiving a response.
CardsBuilder::make() ->items(Article::paginate()) ->fields([ID::make(), Switcher::make('Active')]) ->async()
CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->async()

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

CardsBuilder::make() ->items(Article::paginate()) ->fields([ID::make(), Switcher::make('Active')]) ->name('crud') ->async(asyncEvents: ['cards-updated-crud'])
CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->name('crud')
->async(asyncEvents: ['cards-updated-crud'])

MoonShine already has a set of ready-made events:

  • table-updated-{name} - asynchronous table update by name
  • cards-updated-{name} - asynchronous update of a group of cards by name,
  • form-reset-{name} - reset form values by name,
  • fragment-updated-{name} - updating blade fragment by name.

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

Attributes

You can set any html attributes for the table using the customAttributes() method:

CardsBuilder::make() ->items(Article::paginate()) ->fields([ID::make(), Switcher::make('Active')]) ->customAttributes(['class' => 'custom-cards'])
CardsBuilder::make()
->items(Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->customAttributes(['class' => 'custom-cards'])

Columns

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

columnSpan( int $columnSpan, int $adaptiveColumnSpan = 12 )
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)
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 a list of an element.
To do this, you need to 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'); })
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');
})