Skip to content

Commit

Permalink
Refactor extraMetadata handling in MountedComponent and related classes
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubtobiasz committed Oct 11, 2023
1 parent 0aaa5bf commit 213832a
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
namespace Symfony\UX\LiveComponent\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\UX\LiveComponent\Util\LiveControllerAttributesCreator;
use Symfony\UX\TwigComponent\ComponentStack;
use Symfony\UX\TwigComponent\Event\PostMountEvent;
use Symfony\UX\TwigComponent\Event\PreRenderEvent;

final class DeferLiveComponentSubscriber implements EventSubscriberInterface
Expand All @@ -17,50 +16,58 @@ final class DeferLiveComponentSubscriber implements EventSubscriberInterface

private const DEFAULT_LOADING_TEMPLATE = null;

public function __construct(
private ComponentStack $componentStack,
private LiveControllerAttributesCreator $attributesCreator,
) {
public function onPostMount(PostMountEvent $event): void
{
$data = $event->getData();
if (\array_key_exists('defer', $data)) {
$event->addExtraMetadata('defer', true);
unset($event->getData()['defer']);
}

if (\array_key_exists('loading-template', $data)) {
$event->addExtraMetadata('loading-template', $data['loading-template']);
unset($event->getData()['loading-template']);
}

if (\array_key_exists('loading-tag', $data)) {
$event->addExtraMetadata('loading-tag', $data['loading-tag']);
unset($event->getData()['loading-tag']);
}

$event->setData($data);
}

public function onPreRender(PreRenderEvent $event): void
{
$mountedComponent = $event->getMountedComponent();
$inputProps = $mountedComponent->getInputProps();
$isDeferred = $inputProps['defer'] ?? false;
$isDeferred = $mountedComponent->hasExtraMetadata('defer');

if (!$isDeferred) {
return;
}

$metadata = $event->getMetadata();
$variables = $event->getVariables();
$attributesKey = $metadata->getAttributesVar();

$event->setTemplate('@LiveComponent/deferred.html.twig');

$originalAttributes = $variables[$attributesKey]->all();

$attributes = $originalAttributes;
$attributes = array_filter(
$attributes,
fn ($key) => !\in_array($key, ['defer', 'loading-template', 'loading-tag'], true),
\ARRAY_FILTER_USE_KEY,
);
$variables = $event->getVariables();
$variables['loadingTemplate'] = self::DEFAULT_LOADING_TEMPLATE;
$variables['loadingTag'] = self::DEFAULT_LOADING_TAG;

$variables[$attributesKey] = $attributes;
$variables['loadingTag'] = $originalAttributes['loading-tag'] ?? self::DEFAULT_LOADING_TAG;
$variables['loadingTemplate'] = $originalAttributes['loading-template'] ?? self::DEFAULT_LOADING_TEMPLATE;
if ($mountedComponent->hasExtraMetadata('loading-template')) {
$variables['loadingTemplate'] = $mountedComponent->getExtraMetadata('loading-template');
}

$mountedComponent->setAttributes(
$mountedComponent->getAttributes()->without('defer', 'loading-template', 'loading-tag'),
);
if ($mountedComponent->hasExtraMetadata('loading-tag')) {
$variables['loadingTag'] = $mountedComponent->getExtraMetadata('loading-tag');
}

$event->setVariables($variables);
}

public static function getSubscribedEvents(): array
{
return [PreRenderEvent::class => ['onPreRender', self::PRIORITY]];
return [
PostMountEvent::class => ['onPostMount', self::PRIORITY],
PreRenderEvent::class => ['onPreRender', self::PRIORITY],
];
}
}
16 changes: 13 additions & 3 deletions src/TwigComponent/src/ComponentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ public function mountFromObject(object $component, array $data, ComponentMetadat
}
}

$data = $this->postMount($component, $data);
$postMount = $this->postMount($component, $data);
$data = $postMount['data'];
$extraMetadata = $postMount['extraMetadata'];

// create attributes from "attributes" key if exists
$attributesVar = $componentMetadata->getAttributesVar();
Expand All @@ -109,7 +111,8 @@ public function mountFromObject(object $component, array $data, ComponentMetadat
$componentMetadata->getName(),
$component,
new ComponentAttributes(array_merge($attributes, $data)),
$originalData
$originalData,
$extraMetadata,
);
}

Expand Down Expand Up @@ -188,11 +191,15 @@ private function preMount(object $component, array $data): array
return $data;
}

/**
* @return array{data: array<string, mixed>, extraMetadata: array<string, mixed>}
*/
private function postMount(object $component, array $data): array
{
$event = new PostMountEvent($component, $data);
$this->eventDispatcher->dispatch($event);
$data = $event->getData();
$extraMetadata = $event->getExtraMetadata();

foreach (AsTwigComponent::postMountMethods($component) as $method) {
$newData = $component->{$method->name}($data);
Expand All @@ -202,7 +209,10 @@ private function postMount(object $component, array $data): array
}
}

return $data;
return [
'data' => $data,
'extraMetadata' => $extraMetadata,
];
}

private function isAnonymousComponent(string $name): bool
Expand Down
22 changes: 20 additions & 2 deletions src/TwigComponent/src/Event/PostMountEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
*/
final class PostMountEvent extends Event
{
public function __construct(private object $component, private array $data)
{
public function __construct(
private object $component,
private array $data,
private array $extraMetadata = [],
) {
}

public function getComponent(): object
Expand All @@ -36,4 +39,19 @@ public function setData(array $data): void
{
$this->data = $data;
}

public function getExtraMetadata(): array
{
return $this->extraMetadata;
}

public function addExtraMetadata(string $key, mixed $value): void
{
$this->extraMetadata[$key] = $value;
}

public function removeExtraMetadata(string $key): void
{
unset($this->extraMetadata[$key]);
}
}
10 changes: 2 additions & 8 deletions src/TwigComponent/src/MountedComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@
*/
final class MountedComponent
{
/**
* Any extra metadata that might be useful to set.
*
* @var array<string, mixed>
*/
private array $extraMetadata = [];

/**
* @param array|null $inputProps if the component was just originally created,
* (not hydrated from a request), this is the
Expand All @@ -34,7 +27,8 @@ public function __construct(
private string $name,
private object $component,
private ComponentAttributes $attributes,
private ?array $inputProps = []
private ?array $inputProps = [],
private array $extraMetadata = [],
) {
}

Expand Down

0 comments on commit 213832a

Please sign in to comment.