Skip to content

Commit a9d422e

Browse files
author
matheo
committed
props tag remove props from attributes
1 parent 2d9f300 commit a9d422e

File tree

6 files changed

+49
-11
lines changed

6 files changed

+49
-11
lines changed

src/TwigComponent/src/ComponentTemplateFinder.php renamed to src/TwigComponent/src/AnonymousAnonymousComponentTemplateParser.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
/**
1717
* @author Matheo Daninos <[email protected]>
1818
*/
19-
final class ComponentTemplateFinder implements ComponentTemplateFinderInterface
19+
final class AnonymousAnonymousComponentTemplateParser implements AnonymousComponentTemplateParserInterface
2020
{
2121
public function __construct(
2222
private Environment $environment
@@ -46,4 +46,23 @@ public function findAnonymousComponentTemplate(string $name): ?string
4646

4747
return null;
4848
}
49+
50+
public function findComponentProps(string $name): array
51+
{
52+
$loader = $this->environment->getLoader();
53+
$templateContent = $loader->getSourceContext($this->findAnonymousComponentTemplate($name))->getCode();
54+
55+
$pattern = '/{%\s*props\s*(.*?)\s*%}/';
56+
preg_match($pattern, $templateContent, $matches);
57+
58+
if (isset($matches[1])) {
59+
$props = $matches[1];
60+
$props = preg_replace('/\s/', '', $props);
61+
$propsArray = explode(',', $props);
62+
63+
return array_map(fn (string $propName) => strtok($propName, '='), $propsArray);
64+
}
65+
66+
return [];
67+
}
4968
}

src/TwigComponent/src/AnonymousComponent.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@ final class AnonymousComponent
2222
{
2323
private array $props;
2424

25-
public function mount($props = []): void
25+
public function mount(&$data = [], $propNames = []): void
2626
{
27+
$props = [];
28+
foreach ($propNames as $propName) {
29+
if (isset($data[$propName])) {
30+
$props[$propName] = $data[$propName];
31+
unset($data[$propName]);
32+
}
33+
}
34+
2735
$this->props = $props;
2836
}
2937

src/TwigComponent/src/ComponentTemplateFinderInterface.php renamed to src/TwigComponent/src/AnonymousComponentTemplateParserInterface.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@
1414
/**
1515
* @author Matheo Daninos <[email protected]>
1616
*/
17-
interface ComponentTemplateFinderInterface
17+
interface AnonymousComponentTemplateParserInterface
1818
{
1919
public function findAnonymousComponentTemplate(string $name): ?string;
20+
21+
/**
22+
* @return array<string>
23+
*/
24+
public function findComponentProps(string $name): array;
2025
}

src/TwigComponent/src/ComponentFactory.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ final class ComponentFactory
3030
* @param array<class-string, string> $classMap
3131
*/
3232
public function __construct(
33-
private ComponentTemplateFinderInterface $componentTemplateFinder,
33+
private AnonymousComponentTemplateParserInterface $componentTemplateFinder,
3434
private ServiceLocator $components,
3535
private PropertyAccessorInterface $propertyAccessor,
3636
private EventDispatcherInterface $eventDispatcher,
@@ -77,7 +77,7 @@ public function mountFromObject(object $component, array $data, ComponentMetadat
7777
$originalData = $data;
7878
$data = $this->preMount($component, $data);
7979

80-
$this->mount($component, $data);
80+
$this->mount($component, $data, $componentMetadata);
8181

8282
// set data that wasn't set in mount on the component directly
8383
foreach ($data as $property => $value) {
@@ -103,6 +103,10 @@ public function mountFromObject(object $component, array $data, ComponentMetadat
103103
}
104104

105105
$data[$key] = $value;
106+
107+
if (!\is_scalar($value) && null !== $value) {
108+
throw new \LogicException(sprintf('A "%s" prop was passed when creating the "%s" component. No matching %s property or mount() argument was found, so we attempted to use this as an HTML attribute. But, the value is not a scalar (it\'s a %s). Did you mean to pass this to your component or is there a typo on its name?', $key, $componentMetadata->getName(), $key, get_debug_type($value)));
109+
}
106110
}
107111

108112
return new MountedComponent(
@@ -121,7 +125,7 @@ public function get(string $name): object
121125
return $this->getComponent($name);
122126
}
123127

124-
private function mount(object $component, array &$data): void
128+
private function mount(object $component, array &$data, ComponentMetadata $metadata): void
125129
{
126130
try {
127131
$method = (new \ReflectionClass($component))->getMethod('mount');
@@ -131,7 +135,7 @@ private function mount(object $component, array &$data): void
131135
}
132136

133137
if ($component instanceof AnonymousComponent) {
134-
$component->mount($data);
138+
$component->mount($data, $this->componentTemplateFinder->findComponentProps($metadata->getTemplate()));
135139

136140
return;
137141
}

src/TwigComponent/src/DependencyInjection/TwigComponentExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
use Symfony\Component\DependencyInjection\Exception\LogicException;
1818
use Symfony\Component\DependencyInjection\Extension\Extension;
1919
use Symfony\Component\DependencyInjection\Reference;
20+
use Symfony\UX\TwigComponent\AnonymousAnonymousComponentTemplateParser;
2021
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
2122
use Symfony\UX\TwigComponent\ComponentFactory;
2223
use Symfony\UX\TwigComponent\ComponentRenderer;
2324
use Symfony\UX\TwigComponent\ComponentRendererInterface;
2425
use Symfony\UX\TwigComponent\ComponentStack;
25-
use Symfony\UX\TwigComponent\ComponentTemplateFinder;
2626
use Symfony\UX\TwigComponent\DependencyInjection\Compiler\TwigComponentPass;
2727
use Symfony\UX\TwigComponent\Twig\ComponentExtension;
2828
use Symfony\UX\TwigComponent\Twig\ComponentLexer;
@@ -41,7 +41,7 @@ public function load(array $configs, ContainerBuilder $container): void
4141
throw new LogicException('The TwigBundle is not registered in your application. Try running "composer require symfony/twig-bundle".');
4242
}
4343

44-
$container->register('ux.twig_component.component_template_finder', ComponentTemplateFinder::class)
44+
$container->register('ux.twig_component.component_template_finder', AnonymousAnonymousComponentTemplateParser::class)
4545
->setArguments([
4646
new Reference('twig'),
4747
])
@@ -78,7 +78,7 @@ class_exists(AbstractArgument::class) ? new AbstractArgument(sprintf('Added in %
7878
])
7979
;
8080

81-
$container->register(ComponentTemplateFinder::class, 'ux.twig_component.component_template_finder');
81+
$container->register(AnonymousAnonymousComponentTemplateParser::class, 'ux.twig_component.component_template_finder');
8282

8383
$container->register('ux.twig_component.twig.component_extension', ComponentExtension::class)
8484
->addTag('twig.extension')
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<div class='user-card'>
1+
{% props user %}
2+
3+
<div {{ attributes }} class='user-card'>
24
<p>{{ user.name }}</p>
35
<p>{{ user.email }}</p>
46
</div>

0 commit comments

Comments
 (0)