andersb's avatar

Passing attributes from blade component to subcomponents

Does anyone know how to pass attributes from one blade component to another component used in the first component?

Simplified example

Usage:

<x-search
    class="text-gray-800"
    value="example"
/>
// Should render:
<input class="rounded-md text-gray-800" placeholder="Search ..." name="search" autocomplete="off" value="example"/>
// Renders:
<input class="rounded-md" placeholder="Search ..." name="search" autocomplete="off"/>

Search blade component:

// resources/views/components/search.blade.php

@props(['placeholder' => 'Search ...', 'name' => 'search'])

<x-input :placeholder="$placeholder" :name="$name" autocomplete="off"/>

Generic input component

// resources/views/components/input.blade.php

<input {{ $attributes->merge(['class' => 'rounded-md']) }}/>
0 likes
6 replies
MarianoMoreyra's avatar

Hi @andersb

You should declare the props for the input component too. Also, you should add the placeholder attribute to the input:

// resources/views/components/input.blade.php

@props(['placeholder' => 'Default placeholder...', 'name' => 'generic'])

<input placeholder="{{$placeholder}}" {{ $attributes->merge(['class' => 'rounded-md']) }}"/>

You can test the different defaults by removing the :placeholder attribute from the <x-input/> call and you'll see that it should display the Default placeholder... text instad.

1 like
andersb's avatar

@marianomoreyra this is just a simplified example. The point is that my input component is very generic and should be able to accept any attributes but I don't know which ones. So I should not define any props on that component.

Now the point is that there an attributes class defined when we consume the search component (again this could be any attributes) and that should be passed along to the general input component, but I have no idea how.

I have tries adding {{ $attributes }} but that does not work either - but note that the value is being passed correctly, but the default class (rounded-md) is overriden.

// resources/views/components/search.blade.php

@props(['placeholder' => 'Search ...', 'name' => 'search'])

<x-input placeholder="{{ $placeholder }}" name="{{ $name }}" autocomplete="off" {{ $attributes }}/>

MarianoMoreyra's avatar

@andersb ok I think I understand now.

Try passing the $attributes like this at your search component:

<x-input :placeholder="$placeholder" :name="$name" autocomplete="off" :attributes="$attributes"/>

It worked for me!

andersb's avatar

Now we are talking @marianomoreyra ! :)

That works - with side effects - since setting :attributes="$attributes" overrides any other attributes set normally (meaning properties not defined as props).

So here we are passing properties and also setting the attributes manually:

<x-input :attributes="$attributes" placeholder="{{ $placeholder }}" name="{{ $name }}" autocomplete="off"/>
// Renders: <input class="rounded-md text-gray-800" value="example"/>

which does not work, but instead setting attributes manually and merging other attributes works:

<x-input :attributes="$attributes->merge(['placeholder' => $placeholder, 'name' => $name, 'autocomplete' => 'off'])"/>
// Renders: <input class="rounded-md text-gray-800" placeholder="Search ..." name="search" autocomplete="off" value="example"/>

It seem there is not a simple "pass attributes down" kind of approach, but the proposed solution from @marianomoreyra with assigning the variable :attributes works when also merging any extra attributes to :attributes="$attributes->merge(....)"

Please or to participate in this conversation.