Skip to content

[7.x] Make ComponentAttributeBag Macroable#33354

Merged
taylorotwell merged 1 commit into
laravel:7.xfrom
iAmKevinMcKee:patch-1
Jun 26, 2020
Merged

[7.x] Make ComponentAttributeBag Macroable#33354
taylorotwell merged 1 commit into
laravel:7.xfrom
iAmKevinMcKee:patch-1

Conversation

@iAmKevinMcKee
Copy link
Copy Markdown
Contributor

@iAmKevinMcKee iAmKevinMcKee commented Jun 26, 2020

I think the ComponentAttributeBag should be macroable in general, but specifically because I'd like to submit a PR to Livewire to create a method on the ComponentAttributeBag that easily allows the user to do the following: <x-text-input wire:model="name" />. Once this class is macroable, I can submit the PR to Livewire to make it easier to integrate blade components with Livewire.

You can reference this gist to see how the implementation with Livewire would work, but this would be cleaner to pull out the code in the @php blade directive and put it into a macro.

https://gist.github.com/iAmKevinMcKee/c116282dbbbe34dcd5b3bda4242a3d7a

I've spoken with Caleb and he would accept the PR to Livewire to add this macro once the class is macroable.

I am looking to PR a macro to Livewire to create a method on the ComponentAttributeBag that easily allows the user to do the following: <x-text-input wire:model="name" /> but I would need this class to be Macroable first.
@taylorotwell
Copy link
Copy Markdown
Member

Can you tell me more about how this helps your situation? I have put wire:model on a Blade component before already.

@iAmKevinMcKee
Copy link
Copy Markdown
Contributor Author

Currently, I can hardcode <input wire:model="{{$name}}" /> into the blade component and pass it in like <x-text-input name="firstName" /> and it works.

Inside Livewire Blade Template

<x-text-input model-name="firstName" />

Inside Blade Component (components/text-input.blade.php)

<input wire:model="{{$modelName}}" />
@error($modelName)
{{$message}}
@enderror

The problem is I lose the ability to add a modifier to wire:model like wire:model.lazy or wire:model.debounce.1000ms.

The implementation in the gist solves that issue, and it would be cleaner if we could take that attribute bag iterator logic out of the component itself and put it into a macro.

Then in the blade component (after the PR to livewire), we could do the following inside the blade component:

Usage

Inside Livewire Blade Template

<x-text-input wire:model.lazy="firstName" />

Inside Blade Component (components/text-input.blade.php)

<input {{$attributes->wireModel()}} /> // $attributes->wireModel() = 'wire:model.lazy="firstName"'
@error($attributes->wireModelName()) // $attributes->wireModelName() = 'firstName'
{{$message}}
@enderror

@GrahamCampbell GrahamCampbell changed the title Make ComponentAttributeBag Macroable [7.x] Make ComponentAttributeBag Macroable Jun 26, 2020
@taylorotwell taylorotwell merged commit b5dd4a8 into laravel:7.x Jun 26, 2020
@taylorotwell
Copy link
Copy Markdown
Member

I've also added {{ $attributes->whereStartsWith('wire:model') }}

So you may no longer need the macro after that.

@taylorotwell
Copy link
Copy Markdown
Member

Also added $attributes->filter(fn)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants