diff --git a/src/Illuminate/View/Compilers/ComponentTagCompiler.php b/src/Illuminate/View/Compilers/ComponentTagCompiler.php index e4dcabf61262..f73fd77c0f4c 100644 --- a/src/Illuminate/View/Compilers/ComponentTagCompiler.php +++ b/src/Illuminate/View/Compilers/ComponentTagCompiler.php @@ -203,8 +203,7 @@ protected function componentString(string $component, array $attributes) $parameters = $data->all(); } - return " @component('{$class}', [".$this->attributesToString($parameters, $escapeBound = false).']) -withName(\''.$component.'\'); ?> + return " @component('{$class}', '{$component}', [".$this->attributesToString($parameters, $escapeBound = false).']) withAttributes(['.$this->attributesToString($attributes->all()).']); ?>'; } diff --git a/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php b/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php index 7fc998721330..a9f9d7e7c7ea 100644 --- a/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php +++ b/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php @@ -21,16 +21,16 @@ trait CompilesComponents */ protected function compileComponent($expression) { - [$component, $data] = strpos($expression, ',') !== false - ? array_map('trim', explode(',', trim($expression, '()'), 2)) - : [trim($expression, '()'), '']; + [$component, $alias, $data] = strpos($expression, ',') !== false + ? array_map('trim', explode(',', trim($expression, '()'), 3)) + ['', '', ''] + : [trim($expression, '()'), '', '']; $component = trim($component, '\'"'); $hash = static::newComponentHash($component); if (Str::contains($component, ['::class', '\\'])) { - return static::compileClassComponentOpening($component, $data, $hash); + return static::compileClassComponentOpening($component, $data, $hash, $alias); } return "startComponent{$expression}; ?>"; @@ -53,15 +53,17 @@ public static function newComponentHash(string $component) * Compile a class component opening. * * @param string $component + * @param string $alias * @param string $data * @param string $hash * @return string */ - public static function compileClassComponentOpening(string $component, string $data, string $hash) + public static function compileClassComponentOpening(string $component, string $data, string $hash, string $alias) { return implode("\n", [ '', 'getContainer()->make('.Str::finish($component, '::class').', '.($data ?: '[]').'); ?>', + 'withName('.$alias.'); ?>', 'shouldRender()): ?>', 'startComponent($component->resolveView(), $component->data()); ?>', ]); diff --git a/tests/View/Blade/BladeComponentTagCompilerTest.php b/tests/View/Blade/BladeComponentTagCompilerTest.php index f74008ef5ee1..4ed6bd89ac4b 100644 --- a/tests/View/Blade/BladeComponentTagCompilerTest.php +++ b/tests/View/Blade/BladeComponentTagCompilerTest.php @@ -32,11 +32,9 @@ public function testBasicComponentParsing() $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags('
'); - $this->assertSame("
@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> + $this->assertSame("
@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes(['type' => 'foo','limit' => '5','@click' => 'foo','wire:click' => 'changePlan(\''.e(\$plan).'\')','required' => true]); ?>\n". -"@endcomponentClass @component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> +"@endcomponentClass @component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes([]); ?>\n". '@endcomponentClass
', trim($result)); } @@ -45,8 +43,7 @@ public function testBasicComponentWithEmptyAttributesParsing() { $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags('
'); - $this->assertSame("
@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> + $this->assertSame("
@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes(['type' => '','limit' => '','@click' => '','required' => true]); ?>\n". '@endcomponentClass
', trim($result)); } @@ -55,8 +52,7 @@ public function testDataCamelCasing() { $result = $this->compiler(['profile' => TestProfileComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', ['userId' => '1']) -withName('profile'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', 'profile', ['userId' => '1']) withAttributes([]); ?> @endcomponentClass", trim($result)); } @@ -64,8 +60,7 @@ public function testColonData() { $result = $this->compiler(['profile' => TestProfileComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', ['userId' => 1]) -withName('profile'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', 'profile', ['userId' => 1]) withAttributes([]); ?> @endcomponentClass", trim($result)); } @@ -73,8 +68,7 @@ public function testColonAttributesIsEscapedIfStrings() { $result = $this->compiler(['profile' => TestProfileComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', []) -withName('profile'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', 'profile', []) withAttributes(['src' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute('foo')]); ?> @endcomponentClass", trim($result)); } @@ -82,8 +76,7 @@ public function testColonNestedComponentParsing() { $result = $this->compiler(['foo:alert' => TestAlertComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('foo:alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'foo:alert', []) withAttributes([]); ?> @endcomponentClass", trim($result)); } @@ -91,8 +84,7 @@ public function testColonStartingNestedComponentParsing() { $result = $this->compiler(['foo:alert' => TestAlertComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('foo:alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'foo:alert', []) withAttributes([]); ?> @endcomponentClass", trim($result)); } @@ -100,8 +92,7 @@ public function testSelfClosingComponentsCanBeCompiled() { $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags('
'); - $this->assertSame("
@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> + $this->assertSame("
@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes([]); ?>\n". '@endcomponentClass
', trim($result)); } @@ -140,8 +131,7 @@ public function testComponentsCanBeCompiledWithHyphenAttributes() $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes(['class' => 'bar','wire:model' => 'foo','x-on:click' => 'bar','@click' => 'baz']); ?>\n". '@endcomponentClass', trim($result)); } @@ -150,8 +140,7 @@ public function testSelfClosingComponentsCanBeCompiledWithDataAndAttributes() { $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', ['title' => 'foo']) -withName('alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', ['title' => 'foo']) withAttributes(['class' => 'bar','wire:model' => 'foo']); ?>\n". '@endcomponentClass', trim($result)); } @@ -160,8 +149,7 @@ public function testComponentsCanHaveAttachedWord() { $result = $this->compiler(['profile' => TestProfileComponent::class])->compileTags('Words'); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', []) -withName('profile'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestProfileComponent', 'profile', []) withAttributes([]); ?> @endcomponentClass Words", trim($result)); } @@ -169,8 +157,7 @@ public function testSelfClosingComponentsCanHaveAttachedWord() { $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags('Words'); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes([]); ?>\n". '@endcomponentClass Words', trim($result)); } @@ -179,8 +166,7 @@ public function testSelfClosingComponentsCanBeCompiledWithBoundData() { $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags(''); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', ['title' => \$title]) -withName('alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', ['title' => \$title]) withAttributes(['class' => 'bar']); ?>\n". '@endcomponentClass', trim($result)); } @@ -190,8 +176,7 @@ public function testPairedComponentTags() $result = $this->compiler(['alert' => TestAlertComponent::class])->compileTags(' '); - $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', []) -withName('alert'); ?> + $this->assertSame("@component('Illuminate\Tests\View\Blade\TestAlertComponent', 'alert', []) withAttributes([]); ?> @endcomponentClass", trim($result)); } @@ -207,8 +192,7 @@ public function testClasslessComponents() $result = $this->compiler()->compileTags(''); - $this->assertSame("@component('Illuminate\View\AnonymousComponent', ['view' => 'components.anonymous-component','data' => ['name' => 'Taylor','age' => 31,'wire:model' => 'foo']]) -withName('anonymous-component'); ?> + $this->assertSame("@component('Illuminate\View\AnonymousComponent', 'anonymous-component', ['view' => 'components.anonymous-component','data' => ['name' => 'Taylor','age' => 31,'wire:model' => 'foo']]) withAttributes(['name' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute('Taylor'),'age' => 31,'wire:model' => 'foo']); ?>\n". '@endcomponentClass', trim($result)); } diff --git a/tests/View/Blade/BladeComponentsTest.php b/tests/View/Blade/BladeComponentsTest.php index 3ac1868ee20d..8aefd61a341f 100644 --- a/tests/View/Blade/BladeComponentsTest.php +++ b/tests/View/Blade/BladeComponentsTest.php @@ -10,17 +10,13 @@ public function testComponentsAreCompiled() $this->assertSame('startComponent(\'foo\'); ?>', $this->compiler->compileString('@component(\'foo\')')); } - public function testExtraAttributesCanBePassedToComponents() - { - $this->assertSame('startComponent(\'foo\', ["foo" => "bar"], ["foo" => "bar"]); ?>', $this->compiler->compileString('@component(\'foo\', ["foo" => "bar"], ["foo" => "bar"])')); - } - public function testClassComponentsAreCompiled() { $this->assertSame(' getContainer()->make(Test::class, ["foo" => "bar"]); ?> +withName(\'test\'); ?> shouldRender()): ?> -startComponent($component->resolveView(), $component->data()); ?>', $this->compiler->compileString('@component(\'Test::class\', ["foo" => "bar"])')); +startComponent($component->resolveView(), $component->data()); ?>', $this->compiler->compileString('@component(\'Test::class\', \'test\', ["foo" => "bar"])')); } public function testEndComponentsAreCompiled()