-
-
Notifications
You must be signed in to change notification settings - Fork 340
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
92e2a5e
commit 5bd58dd
Showing
3 changed files
with
195 additions
and
162 deletions.
There are no files selected for viewing
155 changes: 155 additions & 0 deletions
155
src/StimulusBundle/src/Builder/StimulusAttributeBuilder.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
<?php | ||
|
||
namespace Symfony\UX\StimulusBundle\Builder; | ||
|
||
use Symfony\UX\StimulusBundle\Helper\StimulusSyntaxHelper; | ||
|
||
class StimulusAttributeBuilder | ||
{ | ||
private string $controllerName; | ||
private array $actions = []; | ||
private array $values = []; | ||
private array $classes = []; | ||
private array $targets = []; | ||
private array $outlets = []; | ||
private array $attributes = []; | ||
|
||
public static function controller(string $controllerName): self | ||
{ | ||
$builder = new self(); | ||
$builder->controllerName = $controllerName; | ||
|
||
return $builder; | ||
} | ||
|
||
public function action(string $actionName, ?string $eventName = null, array $parameters = []): self | ||
{ | ||
$this->actions[] = [ | ||
'actionName' => $actionName, | ||
'eventName' => $eventName, | ||
'parameters' => $parameters, | ||
]; | ||
|
||
return $this; | ||
} | ||
|
||
public function value(string $key, mixed $value): self | ||
{ | ||
$this->values[$key] = $value; | ||
|
||
return $this; | ||
} | ||
|
||
public function class(string $key, mixed $value): self | ||
{ | ||
$this->classes[$key] = $value; | ||
|
||
return $this; | ||
} | ||
|
||
public function target(string $key, mixed $value): self | ||
{ | ||
$this->targets[$key] = $value; | ||
|
||
return $this; | ||
} | ||
|
||
public function outlet(string $identifier, string $outlet, mixed $selector): self | ||
{ | ||
$this->outlets[] = [ | ||
'identifier' => $identifier, | ||
'outlet' => $outlet, | ||
'selector' => $selector, | ||
]; | ||
|
||
return $this; | ||
} | ||
|
||
public function build(): array | ||
{ | ||
$syntaxHelper = new StimulusSyntaxHelper(); | ||
$controllerName = $syntaxHelper->normalizeControllerName($this->controllerName); | ||
|
||
$this->attributes['data-controller'] = $controllerName; | ||
|
||
//Actions | ||
$this->attributes = array_merge( | ||
$this->attributes, | ||
... | ||
array_map(function (array $actionData) use ($controllerName): array { | ||
$actionName = htmlspecialchars($actionData['actionName']); | ||
$eventName = $actionData['eventName']; | ||
|
||
$action = sprintf('%s#%s', $controllerName, $actionName); | ||
if (null !== $eventName) { | ||
$action = sprintf('%s->%s', htmlspecialchars($eventName), $action); | ||
} | ||
|
||
return ['data-action' => $action]; | ||
}, $this->actions) | ||
); | ||
|
||
//Action Parameters | ||
$this->attributes = array_merge( | ||
$this->attributes, | ||
... | ||
array_map( | ||
function (array $actionData) use ($controllerName, $syntaxHelper): array { | ||
$parameters = []; | ||
|
||
foreach ($actionData['parameters'] as $name => $value) { | ||
$key = $syntaxHelper->normalizeKeyName($name); | ||
$value = $syntaxHelper->getFormattedValue($value); | ||
|
||
$parameters[sprintf( | ||
'data-%s-%s-param', | ||
$controllerName, | ||
$key | ||
)] = htmlspecialchars($value); | ||
} | ||
|
||
return $parameters; | ||
}, | ||
$this->actions | ||
) | ||
); | ||
|
||
//Values | ||
foreach ($this->values as $key => $value) { | ||
if (null === $value) { | ||
continue; | ||
} | ||
|
||
$key = $syntaxHelper->normalizeKeyName($key); | ||
$value = $syntaxHelper->getFormattedValue($value); | ||
|
||
$this->attributes[sprintf('data-%s-%s-value', $controllerName, $key)] = $value; | ||
} | ||
|
||
//Classes | ||
foreach ($this->classes as $key => $class) { | ||
$key = $syntaxHelper->normalizeKeyName($key); | ||
|
||
$this->attributes[sprintf('data-%s-%s-class', $controllerName, $key)] = $class; | ||
} | ||
|
||
//Outlets | ||
foreach ($this->outlets as $outletItem) { | ||
$identifier = $syntaxHelper->normalizeControllerName($outletItem['identifier']); | ||
$outlet = $syntaxHelper->normalizeKeyName($outletItem['outlet']); | ||
|
||
$this->attributes[sprintf('data-%s-%s-outlet', $identifier, $outlet)] = htmlspecialchars( | ||
$outletItem['selector'] | ||
); | ||
} | ||
|
||
//Targets | ||
foreach ($this->targets as $key => $target) { | ||
$key = $syntaxHelper->normalizeKeyName($key); | ||
|
||
$this->attributes[sprintf('data-%s-target', $key)] = htmlspecialchars($target); | ||
} | ||
|
||
return $this->attributes; | ||
} | ||
} |
162 changes: 0 additions & 162 deletions
162
src/StimulusBundle/src/Form/Extension/FormTypeExtension.php
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
namespace Symfony\UX\StimulusBundle\Helper; | ||
|
||
use Stringable; | ||
|
||
use function is_bool; | ||
use function is_callable; | ||
use function is_object; | ||
use function is_scalar; | ||
|
||
class StimulusSyntaxHelper | ||
{ | ||
public function normalizeControllerName(string $controllerName): string | ||
{ | ||
return preg_replace('/^@/', '', str_replace('_', '-', str_replace('/', '--', $controllerName))); | ||
} | ||
|
||
public function normalizeKeyName(string $str): string | ||
{ | ||
// Adapted from ByteString::camel | ||
$str = ucfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $str)))); | ||
|
||
// Adapted from ByteString::snake | ||
return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1-\2', $str)); | ||
} | ||
|
||
public function getFormattedValue(mixed $value): string | ||
{ | ||
if ($value instanceof Stringable || (is_object($value) && is_callable([$value, '__toString']))) { | ||
$value = (string)$value; | ||
} elseif (!is_scalar($value)) { | ||
$value = json_encode($value); | ||
} elseif (is_bool($value)) { | ||
$value = $value ? 'true' : 'false'; | ||
} | ||
|
||
return (string)$value; | ||
} | ||
} |