Context data
Thus far, we have created fairly basic pattern definitions with simple context data attached. To remind you, hereâs our basic sample component:
1
2
3
4
5
6
7
8
{{-- /resources/views/components/button.blade.php --}}
<button
{{ $attributes->class([
"border rounded-md border-sky-400 shadow-md ..."
]) }}
>
{{ $slot }}
</button>
And hereâs a sample pattern definition:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// tests/Patterns/Components/Button.php
namespace Tests\Patterns\Components;
use Illuminate\View\View;
use njpanderson\Braid\Base\ComponentPattern;
use njpanderson\Braid\Contracts\PatternContext;
class Button extends ComponentPattern {
public function contextData(string $context): PatternContext|View
{
return $this->makeContext(
slot: 'Button'
);
}
}
Thatâs all well and good, but what if our component is a little more complex? like the following example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{{-- /resources/views/components/card.blade.php --}}
@props(['title', 'image', 'link', 'link-text' ])
<div
{{ $attributes->class([
'w-full group mx-auto shadow-lg rounded border hover:border-blue-400 bg-slate-100 hover:bg-blue-100'
])}}
{{ $attributes }}
>
@if (isset($image))
<picture class="w-full">
<source srcset="{{ $image }}"/>
<img class="w-full h-[150px] object-cover opacity-80 group-hover:opacity-100" src="{{ $image }}"/>
</picture>
@endif
<h2 class="pt-4 px-4 font-semibold text-lg">
<a href="#" class="group-hover:text-blue-600">{{ $title }}</a>
</h2>
<div class="px-4 pb-4">
{!! $slot !!}
@if (isset($link))
<p class="mt-2 flex gap-x-2 items-center justify-end">
<a href="{{ $link }}" class="hover:underline">{{ $linkText ?? $title }}</a>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="m12.75 15 3-3m0 0-3-3m3 3h-7.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /></svg>
</p>
@endif
</div>
</div>
How do we test this component?
Without a pattern library solution, you could perhaps make a âshowcaseâ style template within your Laravel app, but it would get clunky fast, be situated inside other templates, and you still wouldnât get useful reviewing features such as a status log or responsive layout switching1.
Siloing of patterns and context capability is where Braid really shines. âď¸
Using contexts
One of Braidâs useful features is to allow component developers to define various views, or contexts, of their components using a pattern definition. This means you can show your components off in various ways, all within the pattern library, without making material changes to the component itself.
Defining contexts
Each and every Braid pattern comes with a default context, appropriately named default
. Braid doesnât show you this one; it comes for free with the base pattern class and when you load a pattern inside Braid, the default context is shown first.
If youâd like to follow along with your own code, you can copy the above card
component and place it at /resources/views/components/card.blade.php
within your project. If this collides with an existing component, feel free to use a different name â just remember to either rename your pattern or define $viewName
accordingly.
You can then use the following command to create an associated pattern at Tests\Patterns\Components\Card
in artisan:
1
php artisan braid:make:pattern Components/Card --type=component
To define more contexts in your pattern definition, we can add to an array named $contexts
:
1
2
3
4
5
6
7
8
9
10
/**
* Pattern contexts
*
* @var array
*/
protected $contexts = [
'no-image',
'no-link',
'long-description'
];
Context labels are normally generated from the name. You can customise the label by providing a key and value pair instead of just the value (e.g. $contexts = [ 'no-image' => 'No Image!', ...]
). The key will be used to generate the URL and identifier, the value will be used verbatim for the label.
This will show up within Braid as a list of links beneath the main pattern:

And clicking on each of them will⌠Do absolutely nothing. đ¤¨
You might even be treated to a template error if youâve already defined the component from the example above. Donât worry, this is to be expected! Read onâŚ
Defining context data
Now we need to define the actual context data with each named context.
How you do this is up to you, but my usual approach is to use a switch, combined with the built in method named makeContext
.
Letâs define a baseline context first. This will return the same data regardless of the context required, but itâs a good starting point:
1
2
3
4
5
6
7
8
9
10
11
public function contextData(string $context): PatternContext|View
{
return $this->makeContext(
attributes: [
'image' => 'https://picsum.photos/600/150',
'title' => 'About us',
'link' => '/about-us'
],
slot: '<p>' . fake()->sentence(rand(6, 15)) . '</p>'
);
}
Thereâs a few things going on here already:
$this->makeContext
is a built in method which returns an instance ofnjpanderson\Braid\Contracts\PatternContext
. This (or a view) is a required return value frommakeContext
.makeContext
supports three arguments2, two of which are being used here:attributes
defines a simple array of attributes, which, in the context of a Laravel component, would be sent to the component as html-like attributes.slot
defines the slot data for a component. Usually expressed on the component side with{{ $slot }}
- Scoped slots are also supported, but letâs not get into that here. See the Patterns reference page for more information.
- An instance of faker (
fake()
) is also being utilised to provide a random sentence. Due to the dynamic nature of PHP, we can write complex logic to provide context information as needed, without having to manually edit the patterns each time.
Adding the remaining contexts
Great start, but weâre only defining a single context at the moment, and our poor little $context
argument is going completely unused. Letâs improve on that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public function contextData(string $context): PatternContext|View
{
switch ($context) {
case 'no-image':
return $this->makeContext(
attributes: [
'title' => 'About us',
'link' => '/about-us'
],
slot: '<p>' . fake()->sentence(rand(6, 15)) . '</p>'
);
case 'no-link':
return $this->makeContext(
attributes: [
'image' => 'https://picsum.photos/600/150',
'title' => 'About us'
],
slot: '<p>' . fake()->sentence(rand(6, 15)) . '</p>'
);
case 'long-description':
return $this->makeContext(
attributes: [
'image' => 'https://picsum.photos/600/150',
'title' => 'About us'
],
slot: '<p>' . fake()->sentence(rand(25, 40)) . '</p>'
);
default:
return $this->makeContext(
attributes: [
'image' => 'https://picsum.photos/600/150',
'title' => 'About us',
'link' => '/about-us'
],
slot: '<p>' . fake()->sentence(rand(6, 15)) . '</p>'
);
}
}
This example defines the data for all three contexts. no-image
, no-link
, and long-description
, plus the default
context as before.
Now, when viewing the component in those three different contexts, it will take on unique appearances:



And in all four cases, the component file itself remains the same.
Checking context data
If youâre implementing patterns from the pattern library, the knowing what attributes, slots etc the pattern needs can come in handy. You can see the context data in the pattern tools panel at the bottom of every pattern display:

In fact, this tab can show all kinds of data, such as booleans, arrays, nested data and even contains syntax highlighting for your slot payloads. Experiment with it and see what works!
For more information, see the Patterns reference page.
-
Some developer tools can do this, but do (or should) your stakeholders, designers and account managers know how to use them? ↩
-
Donât recognise the argument syntax here? Itâs part of PHPâs named arguments feature. ↩