Passing conditional attributes to component
Laravel Version
12.28.1
PHP Version
8.4.11
Database Driver & Version
NA
Description
I know we can pass attributes to components:
<x-card disabled><</x-card>
but it seems we cannot pass conditional attributes to components:
<x-card {{ $conditional ? '' : 'disabled' }}></x-card>
This results in a compilation error of "syntax error, unexpected token "endif", expecting end of file".
Is there another way to handle this, or do we need to adjust the regex to handle this?
Steps To Reproduce
<x-card {{ $conditional ? '' : 'disabled' }}></x-card>
Isn't that
<x-card @disabled(!$conditional)></x-card>
?
it is, but I dumbed it down to show a simple example of how {{ }} in a component does not work.
also, please try the code you suggest before commenting. your example also does not work.
@crynobone what additional info would you like?
It's literally from the docs: https://laravel.com/docs/12.x/blade#additional-attributes
Maybe, this should also be a possible blade extension point 🤔
I believe several attempts have been made to add an @attributes helper in the past. One of which is #52783.
@browner12 Why the thumbsdown? Please explain to me why this—in your opinion—is not covered by the docs
because the @disabled directive is shown on a normal HTML element, NOT a Blade component, so it is not relevant here.
Thanks for the explanation.
I believe this will be solved by #57235
@browner12 unfortunately it would not. With that PR, if $conditional is false then this:
<x-card @maybe('disabled', $conditional)></x-card>
would output this:
<x-card disabled="false"></x-card>
lol, is this the root of the whole debate going on in that PR?
Yes, at least that's what my issue is with it.
ok, gotcha. i've been avoiding jumping into that discussion, but now I might have to read it through and add my 2 cents.
@browner12 unfortunately it would not. With that PR, if
$conditionalis false then this:<x-card @maybe('disabled', $conditional)> would output this:
<\x-card disabled="false">
@willrowe You don't even need what I propose in the other PR to achieve what you try here.
<x-card :disabled="$conditional" />
renders as <x-card></x-card> for false and <x-card disabled="disabled"></x-card> for true
Which is exactly the behaviour that y'all expect for booleans. And conform to the HTML spec that says disabled="disabled" equals disabled
For everything else than booleans we have solutions too. Why would we clutter the component syntax with something like asked for in the issue? @browner12 can you give an example or two?
Instead of writing:
<x-card {{ $conditional ? '' : 'disabled' }}>
You can make the intent clearer by passing a dedicated @prop to the component:
<x-card :disabled="$condition" />
Then, inside the component, define the prop and handle it explicitly:
@props(['disabled' => false])
<div @if($disabled) disabled @endif></div>
This approach improves readability. Anyone looking at the component implementation can immediately notice that the card can be disabled, without having to inspect every individual component call to understand the behavior.
that's a valid option, but there are scenarios when I may not want to define that behavior in the component itself, and rather allow the calling code to have full control.
@AhmedAlaa4611 does this work as well?
<x-card :disabled="$condition" />
<!-- in x-card component -->
<div {{ $attributes }}></div>
that's a valid option, but there are scenarios when I may not want to define that behavior in the component itself, and rather allow the calling code to have full control.
I asked you for examples above. Could you please give some?
@AhmedAlaa4611 does this work as well?
<x-card :disabled="$condition" />
<!-- in x-card component --><div {{ $attributes }}></div>
It does. That's what I meant above.
<x-input :value="$text" :disabled="$condition" :style="$foo"/>
<!-- x-input -->
<input type="name" value="{{ $value }}" {{ $attributes }} />
<!-- disabled: true / style: 'foo' -->
<input type="name" value="bar" disabled="disabled" style="foo" />
<!-- disabled: false / style: null -->
<input type="name" value="bar" />
Seems like Browner12 cannot come up with a real world example. Given that two people provided working solutions, and that we want the framework to be clean and maintainable, this should probably be closed @crynobone.
I can, but you were obviously upset when you wrote the comments, and I have no interest in committing more energy to this right now.
I can, but you were obviously upset when you wrote the comments, and I have no interest in committing more energy to this right now.
I joined here because the objective of this issue was linked to the @maybe PR. I literally added helpful comments in here. Wouldn't do that if I am upset. I am not here to dislike your things because you did so with mine. No hard feelings; as you probably know I am in your favour of many of your contributions. 🤝 Not everyone is a native speaker; maybe you interpret too much in it?
You say the maintainability of the framework is in your best interest. So please add examples that we can discuss to achieve this goal together.
Apologies for assuming. Strong opinions loosely held sometimes doesn't translate over the internet.
I'm just gonna let your PR play out. I can probably make whatever solution you land on work for me.