Skip to content

Commit

Permalink
Feat(web-twig): Introduce filter for Boolean props
Browse files Browse the repository at this point in the history
  * converts stringified boolean prop into boolean representation
  • Loading branch information
literat committed Jul 30, 2022
1 parent e352145 commit 47d3872
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 40 deletions.
1 change: 1 addition & 0 deletions packages/web-twig/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Introduce `Pill` component
- Introduce `Tabs` component
- Refactor components directory tree
- Introduce filter for conversion of stringified boolean props

## 1.7.0 - 2022-05-09
- Add Svg twig extension for optimal loading of svg files as inline
Expand Down
12 changes: 6 additions & 6 deletions packages/web-twig/src/Resources/components/Button/Button.twig
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{# API #}
{%- set _class = props.class | default(null) -%}
{%- set _color = props.color | default('primary') -%}
{%- set _isBlock = props.isBlock | default(false) -%}
{%- set _isDisabled = props.isDisabled | default(false) -%}
{%- set _isSquare = props.isSquare | default(false) -%}
{%- set _isBlock = props.isBlock | boolprop | default(false) -%}
{%- set _isDisabled = props.isDisabled | boolprop | default(false) -%}
{%- set _isSquare = props.isSquare | boolprop | default(false) -%}
{%- set _onClick = props.onClick | default(null) -%}
{%- set _type = props.type | default('button') -%}

{# Class names #}
{%- set _colorClassName = _spiritClassPrefix ~ 'Button--' ~ _color -%}
{%- set _rootBlockClassName = _isBlock == 'true' ? _spiritClassPrefix ~ 'Button--block' : null -%}
{%- set _rootBlockClassName = _isBlock ? _spiritClassPrefix ~ 'Button--block' : null -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'Button' -%}
{%- set _rootSquareClassName = _isSquare == 'true' ? _spiritClassPrefix ~ 'Button--square' : null -%}
{%- set _rootSquareClassName = _isSquare ? _spiritClassPrefix ~ 'Button--square' : null -%}

{# Attributes #}
{%- set _disabledAttr = _isDisabled == 'true' ? 'disabled' : null -%}
{%- set _disabledAttr = _isDisabled ? 'disabled' : null -%}
{%- set _onClickAttr = _onClick ? 'onclick="' ~ _onClick ~'"' : null -%}

{# Miscellaneous #}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
{%- set _class = props.class | default(null) -%}
{%- set _color = props.color | default('primary') -%}
{%- set _href = props.href -%}
{%- set _isBlock = props.isBlock | default(false) -%}
{%- set _isDisabled = props.isDisabled | default(false) -%}
{%- set _isSquare = props.isSquare | default(false) -%}
{%- set _isBlock = props.isBlock | boolprop | default(false) -%}
{%- set _isDisabled = props.isDisabled | boolprop | default(false) -%}
{%- set _isSquare = props.isSquare | boolprop | default(false) -%}
{%- set _onClick = props.onClick | default(null) -%}
{%- set _target = props.target | default(null) -%}
{%- set _title = props.title | default(null) -%}

{# Class names #}
{%- set _colorClassName = _spiritClassPrefix ~ 'Button--' ~ _color -%}
{%- set _rootBlockClassName = _isBlock == 'true' ? _spiritClassPrefix ~ 'Button--block' : null -%}
{%- set _rootBlockClassName = _isBlock ? _spiritClassPrefix ~ 'Button--block' : null -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'Button' -%}
{%- set _rootSquareClassName = _isSquare == 'true' ? _spiritClassPrefix ~ 'Button--square' : null -%}
{%- set _rootSquareClassName = _isSquare ? _spiritClassPrefix ~ 'Button--square' : null -%}

{# Attributes #}
{%- set _disabledAttr = _isDisabled == 'true' ? 'disabled' : null -%}
{%- set _disabledAttr = _isDisabled ? 'disabled' : null -%}
{%- set _onClickAttr = _onClick ? 'onclick="' ~ _onClick ~'"' : null -%}
{%- set _targetAttr = _target ? 'target="' ~ _target ~ '"' : null -%}
{%- set _titleAttr = _title ? 'title="' ~ _title ~ '"' : null -%}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{# API #}
{%- set _class = props.class | default(null) -%}
{%- set _id = props.id | default(null) -%}
{%- set _isChecked = props.isChecked | default(false) -%}
{%- set _isDisabled = props.isDisabled | default(false) -%}
{%- set _isLabelHidden = props.isLabelHidden | default(false) -%}
{%- set _isRequired = props.isRequired | default(false) -%}
{%- set _isChecked = props.isChecked | boolprop | default(false) -%}
{%- set _isDisabled = props.isDisabled | boolprop | default(false) -%}
{%- set _isLabelHidden = props.isLabelHidden | boolprop | default(false) -%}
{%- set _isRequired = props.isRequired | boolprop | default(false) -%}
{%- set _label = props.label | default(null) -%}
{%- set _message = props.message | default(null) -%}
{%- set _name = props.name | default(null) -%}
Expand All @@ -14,18 +14,18 @@
{# Class names #}
{%- set _inputClassName = _spiritClassPrefix ~ 'CheckboxField__input' -%}
{%- set _labelClassName = _spiritClassPrefix ~ 'CheckboxField__label' -%}
{%- set _labelHiddenClassName = _isLabelHidden == 'true' ? _spiritClassPrefix ~ 'CheckboxField__label--hidden' : null -%}
{%- set _labelRequiredClassName = _isRequired == 'true' ? _spiritClassPrefix ~ 'CheckboxField__label--required' : null -%}
{%- set _labelHiddenClassName = _isLabelHidden ? _spiritClassPrefix ~ 'CheckboxField__label--hidden' : null -%}
{%- set _labelRequiredClassName = _isRequired ? _spiritClassPrefix ~ 'CheckboxField__label--required' : null -%}
{%- set _messageClassName = _spiritClassPrefix ~ 'CheckboxField__message' -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'CheckboxField' -%}
{%- set _rootDisabledClassName = _isDisabled == 'true' ? _spiritClassPrefix ~ 'CheckboxField--disabled' : null -%}
{%- set _rootDisabledClassName = _isDisabled ? _spiritClassPrefix ~ 'CheckboxField--disabled' : null -%}
{%- set _rootValidationStateClassName = _validationState ? _spiritClassPrefix ~ 'CheckboxField--' ~ _validationState : null -%}
{%- set _textClassName = _spiritClassPrefix ~ 'CheckboxField__text' -%}

{# Attributes #}
{%- set _checkedAttr = _isChecked == 'true' ? 'checked' : null -%}
{%- set _disabledAttr = _isDisabled == 'true' ? 'disabled' : null -%}
{%- set _requiredAttr = _isRequired == 'true' ? 'required' : null -%}
{%- set _checkedAttr = _isChecked ? 'checked' : null -%}
{%- set _disabledAttr = _isDisabled ? 'disabled' : null -%}
{%- set _requiredAttr = _isRequired ? 'required' : null -%}
{%- set _valueAttr = _value ? 'value="' ~ _value ~'"' : null -%}

{# Miscellaneous #}
Expand Down
8 changes: 4 additions & 4 deletions packages/web-twig/src/Resources/components/Link/Link.twig
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
{%- set _class = props.class | default(null) -%}
{%- set _color = props.color | default('primary') -%}
{%- set _href = props.href -%}
{%- set _isDisabled = props.isDisabled | default(false) -%}
{%- set _isUnderlined = props.isUnderlined | default(false) -%}
{%- set _isDisabled = props.isDisabled | boolprop | default(false) -%}
{%- set _isUnderlined = props.isUnderlined | boolprop | default(false) -%}
{%- set _onClick = props.onClick | default(null) -%}
{%- set _target = props.target | default(null) -%}
{%- set _title = props.title | default(null) -%}

{# Class names #}
{%- set _colorClassName = _spiritClassPrefix ~ 'link-' ~ _color -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'link' -%}
{%- set _rootDisabledClassName = _isDisabled == 'true' ? _spiritClassPrefix ~ 'link-disabled' : null -%}
{%- set _rootUnderlinedClassName = _isUnderlined == 'true' ? _spiritClassPrefix ~ 'link-underlined' : null -%}
{%- set _rootDisabledClassName = _isDisabled ? _spiritClassPrefix ~ 'link-disabled' : null -%}
{%- set _rootUnderlinedClassName = _isUnderlined ? _spiritClassPrefix ~ 'link-underlined' : null -%}

{# Attributes #}
{%- set _onClickAttr = _onClick ? 'onclick="' ~ _onClick ~'"' : null -%}
Expand Down
4 changes: 2 additions & 2 deletions packages/web-twig/src/Resources/components/Tabs/TabLink.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
{%- set _class = props.class | default(null) -%}
{%- set _href = props.href | default(null) -%}
{%- set _id = props.id | default(null) -%}
{%- set _isSelected = props.isSelected | default(false) -%}
{%- set _isSelected = props.isSelected | boolprop | default(false) -%}

{# Class names #}
{%- set _isSelectedClassName = _isSelected == 'true' ? 'is-selected' : null -%}
{%- set _isSelectedClassName = _isSelected ? 'is-selected' : null -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'Tabs__link' -%}

{# Attributes #}
Expand Down
4 changes: 2 additions & 2 deletions packages/web-twig/src/Resources/components/Tabs/TabPane.twig
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{# API #}
{%- set _class = props.class | default(null) -%}
{%- set _id = props.id | default(null) -%}
{%- set _isSelected = props.isSelected | default(false) -%}
{%- set _isSelected = props.isSelected | boolprop | default(false) -%}
{%- set _label = props.label | default(null) -%}

{# Class names #}
{%- set _isSelectedClassName = _isSelected == 'true' ? 'is-selected' : null -%}
{%- set _isSelectedClassName = _isSelected ? 'is-selected' : null -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'Tabs-pane' -%}

{# Attributes #}
Expand Down
20 changes: 10 additions & 10 deletions packages/web-twig/src/Resources/components/TextField/TextField.twig
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{# API #}
{%- set _class = props.class | default(null) -%}
{%- set _id = props.id | default(null) -%}
{%- set _isDisabled = props.isDisabled | default(false) -%}
{%- set _isFluid = props.isFluid | default(false) -%}
{%- set _isLabelHidden = props.isLabelHidden | default(false) -%}
{%- set _isRequired = props.isRequired | default(false) -%}
{%- set _isDisabled = props.isDisabled | boolprop | default(false) -%}
{%- set _isFluid = props.isFluid | boolprop | default(false) -%}
{%- set _isLabelHidden = props.isLabelHidden | boolprop | default(false) -%}
{%- set _isRequired = props.isRequired | boolprop | default(false) -%}
{%- set _label = props.label -%}
{%- set _message = props.message | default(null) -%}
{%- set _name = props.name | default(null) -%}
Expand All @@ -16,18 +16,18 @@
{# Class names #}
{%- set _inputClassName = _spiritClassPrefix ~ 'TextField__input' -%}
{%- set _labelClassName = _spiritClassPrefix ~ 'TextField__label' -%}
{%- set _labelHiddenClassName = _isLabelHidden == 'true' ? _spiritClassPrefix ~ 'TextField__label--hidden' : null -%}
{%- set _labelRequiredClassName = _isRequired == 'true' ? _spiritClassPrefix ~ 'TextField__label--required' : null -%}
{%- set _labelHiddenClassName = _isLabelHidden ? _spiritClassPrefix ~ 'TextField__label--hidden' : null -%}
{%- set _labelRequiredClassName = _isRequired ? _spiritClassPrefix ~ 'TextField__label--required' : null -%}
{%- set _messageClassName = _spiritClassPrefix ~ 'TextField__message' -%}
{%- set _rootClassName = _spiritClassPrefix ~ 'TextField' -%}
{%- set _rootDisabledClassName = _isDisabled == 'true' ? _spiritClassPrefix ~ 'TextField--disabled' : null -%}
{%- set _rootFluidClassName = _isFluid == 'true' ? _spiritClassPrefix ~ 'TextField--fluid' : null -%}
{%- set _rootDisabledClassName = _isDisabled ? _spiritClassPrefix ~ 'TextField--disabled' : null -%}
{%- set _rootFluidClassName = _isFluid ? _spiritClassPrefix ~ 'TextField--fluid' : null -%}
{%- set _rootValidationStateClassName = _validationState ? _spiritClassPrefix ~ 'TextField--' ~ _validationState : null -%}

{# Attributes #}
{%- set _disabledAttr = _isDisabled == 'true' ? 'disabled' : null -%}
{%- set _disabledAttr = _isDisabled ? 'disabled' : null -%}
{%- set _placeholderAttr = _placeholder ? 'placeholder="' ~ _placeholder ~'"' : null -%}
{%- set _requiredAttr = _isRequired == 'true' ? 'required' : null -%}
{%- set _requiredAttr = _isRequired ? 'required' : null -%}
{%- set _valueAttr = _value ? 'value="' ~ _value ~'"' : null -%}

{# Miscellaneous #}
Expand Down
4 changes: 4 additions & 0 deletions packages/web-twig/src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ services:
Lmc\SpiritWebTwigBundle\Twig\SvgExtension:
tags:
- { name: twig.extension }

Lmc\SpiritWebTwigBundle\Twig\BoolpropExtension:
tags:
- { name: twig.extension }
28 changes: 28 additions & 0 deletions packages/web-twig/src/Twig/BoolpropExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Lmc\SpiritWebTwigBundle\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class BoolpropExtension extends AbstractExtension
{
public function getFilters()
{
return [
new TwigFilter('boolprop', [$this, 'convert2Boolean'], [
'is_safe' => ['html'],
]),
];
}

/**
* @param mixed $prop
*/
public function convert2Boolean($prop): bool
{
return filter_var($prop, FILTER_VALIDATE_BOOLEAN);
}
}
4 changes: 4 additions & 0 deletions packages/web-twig/tests/Helper/TwigHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Lmc\SpiritWebTwigBundle\DependencyInjection\CompilerPass\OverrideServiceCompilerPass;
use Lmc\SpiritWebTwigBundle\DependencyInjection\SpiritWebTwigExtension;
use Lmc\SpiritWebTwigBundle\Twig\BoolpropExtension;
use Lmc\SpiritWebTwigBundle\Twig\PropsExtension;
use Lmc\TwigXBundle\Compiler\ComponentLexer;
use Twig\Environment;
Expand Down Expand Up @@ -40,6 +41,9 @@ public static function setup(
$propsExtension = new PropsExtension();
$twig->addExtension($propsExtension);

$boolpropExtension = new BoolpropExtension();
$twig->addExtension($boolpropExtension);

if ($prefix) {
$twig->addGlobal(OverrideServiceCompilerPass::GLOBAL_PREFIX_TWIG_VARIABLE, $prefix);
}
Expand Down
58 changes: 58 additions & 0 deletions packages/web-twig/tests/Twig/BoolpropExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Lmc\SpiritWebTwigBundle\Twig;

use Mockery as m;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Loader\LoaderInterface;
use Twig\Source;

class BoolpropExtensionTest extends TestCase
{
private BoolpropExtension $boolpropExtension;

public function setUp(): void
{
$this->boolpropExtension = new BoolpropExtension();
}

/**
* @param mixed $prop
* @dataProvider boolpropDataProvider
*/
public function testShouldConvertPropValueIntoBoolean($prop, bool $expectedValue): void
{
$convertedValue = $this->boolpropExtension->convert2Boolean($prop);

$this->assertSame($expectedValue, $convertedValue);
}

/**
* @return array<string, array<int, bool|int|string|null>>
*/
public function boolpropDataProvider(): array
{
return [
'bool true' => [true, true],
'string true' => ['true', true],
'number one' => [1, true],
'number one in string' => ['1', true],
'string `on`' => ['on', true],
'string `yes`' => ['yes', true],
'bool false' => [false, false],
'string false' => ['false', false],
'number zero' => [0, false],
'number zero in string' => ['0', false],
'string `off`' => ['off', false],
'string `no`' => ['no', false],
'some string' => ['asfdsafdsf', false],
'empty prop' => ['', false],
'null prop' => [null, false],
];
}
}

0 comments on commit 47d3872

Please sign in to comment.