diff --git a/src/Compiler/SlotCompiler.php b/src/Compiler/SlotCompiler.php index e6ddf56..9474fe8 100644 --- a/src/Compiler/SlotCompiler.php +++ b/src/Compiler/SlotCompiler.php @@ -26,24 +26,33 @@ public function __construct( public function compile(string $slotsVariableName, array $children): string { $output = ''; + $hasExplicitDefault = $this->hasExplicitDefaultSlot($children); - // Compile implicit default slot from loose content (non-SlotNode children) - if (! $this->hasExplicitDefaultSlot($children)) { - $output .= $this->compileSlot('slot', $this->renderLooseContent($children), '[]', $slotsVariableName) . "\n"; + if (! $hasExplicitDefault) { + $output .= '<' . '?php ob_start(); ?>'; } - // Compile each named slot foreach ($children as $child) { if ($child instanceof SlotNode) { - $output .= $this->compileSlot( + $output .= ' ' . $this->compileSlot( $this->resolveSlotName($child), $this->renderChildren($child->children), $this->compileSlotAttributes($child), $slotsVariableName, - ) . "\n"; + ); + } else { + $output .= $child->render(); } } + if (! $hasExplicitDefault) { + $contentHandler = $this->manager->isFolding() + ? '$__blaze->processPassthroughContent(\'trim\', trim(ob_get_clean()))' + : 'trim(ob_get_clean())'; + + $output .= '<' . '?php ' . $slotsVariableName . '[\'slot\'] = new \Illuminate\View\ComponentSlot(' . $contentHandler . ', []); ?>' . "\n"; + } + return $output; } @@ -63,37 +72,6 @@ protected function hasExplicitDefaultSlot(array $children): bool return false; } - /** - * Render non-SlotNode children as the default slot content. - * - * @param array $children - */ - protected function renderLooseContent(array $children): string - { - $content = ''; - $previousWasSlot = false; - - foreach ($children as $child) { - if ($child instanceof SlotNode) { - $previousWasSlot = true; - continue; - } - - $rendered = $child->render(); - - // Laravel's slot compilation consumes the newline after and adds a leading space. - // We match this by prepending a space and stripping any leading newline. - if ($previousWasSlot) { - $rendered = ' ' . preg_replace('/^\n/', '', $rendered); - } - - $content .= $rendered; - $previousWasSlot = false; - } - - return $content; - } - /** * Compile a slot into ob_start/ob_get_clean code. */ diff --git a/tests/ComparisonTest.php b/tests/ComparisonTest.php index e9ffa12..54ff918 100644 --- a/tests/ComparisonTest.php +++ b/tests/ComparisonTest.php @@ -99,4 +99,26 @@ BLADE +)); + +test('conditional slots', fn () => compare(<<<'BLADE' + + @if(false) + + Header + + @endif + + BLADE +)); + +test('foldable conditional slots', fn () => compare(<<<'BLADE' + + @if(false) + + Header + + @endif + + BLADE )); \ No newline at end of file diff --git a/tests/Compiler/CompilerTest.php b/tests/Compiler/CompilerTest.php index 00bea7b..0f59d03 100644 --- a/tests/Compiler/CompilerTest.php +++ b/tests/Compiler/CompilerTest.php @@ -47,9 +47,11 @@ ' ', ' \'mt-8\']; ?> ', ' ', - ' Body ', + ' ', ' Header \'p-2\']); ?> ', + 'Body ', ' Footer \'mt-4\']); ?> ', + ' ', 'pushData($__attrs'. $hash .'); ?> ', 'pushSlots($__slots'. $hash .'); ?> ', ' ',