Skip to content

Commit

Permalink
[TwigComponent][LiveComponent] Seek only for live components in stack
Browse files Browse the repository at this point in the history
  • Loading branch information
sneakyvv committed Sep 5, 2023
1 parent 24338fb commit 9815f9f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
23 changes: 21 additions & 2 deletions src/LiveComponent/src/EventListener/DataModelPropsSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Util\ModelBindingParser;
use Symfony\UX\TwigComponent\ComponentStack;
use Symfony\UX\TwigComponent\Event\PreMountEvent;
use Symfony\UX\TwigComponent\MountedComponent;

/**
* Parses the "data-model" key, which triggers extra props to be passed in.
Expand Down Expand Up @@ -54,8 +56,9 @@ public function onPreMount(PreMountEvent $event): void
unset($data['dataModel']);
$data['data-model'] = $dataModel;

// the parent is still listed as the "current" component at this point
$parentMountedComponent = $this->componentStack->getCurrentComponent();
// find the first parent of the component about to be rendered that is a Live Component
// only those can have properties controlled via the data-model attribute
$parentMountedComponent = $this->getCurrentLiveComponent($this->componentStack);
if (null === $parentMountedComponent) {
throw new \LogicException('You can only pass "data-model" when rendering a component when you\'re rendering inside of a parent component.');
}
Expand All @@ -76,4 +79,20 @@ public static function getSubscribedEvents(): array
PreMountEvent::class => 'onPreMount',
];
}

private function getCurrentLiveComponent(ComponentStack $componentStack): ?MountedComponent
{
foreach ($componentStack as $mountedComponent) {
if ($this->isLiveComponent($mountedComponent->getComponent()::class)) {
return $mountedComponent;
}
}

return null;
}

private function isLiveComponent(string $classname): bool
{
return [] !== (new \ReflectionClass($classname))->getAttributes(AsLiveComponent::class);
}
}
10 changes: 9 additions & 1 deletion src/TwigComponent/src/ComponentStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @internal
*/
class ComponentStack
class ComponentStack implements \IteratorAggregate
{
/**
* @var MountedComponent[]
Expand Down Expand Up @@ -60,4 +60,12 @@ public function hasParentComponent(): bool
{
return (bool) $this->getParentComponent();
}

/**
* @return MountedComponent[]|\ArrayIterator
*/
public function getIterator(): \Traversable
{
return new \ArrayIterator(array_reverse($this->components));
}
}

0 comments on commit 9815f9f

Please sign in to comment.