Skip to content

Commit

Permalink
Merge pull request #27 from tales-from-a-dev/feature/switch-label-con…
Browse files Browse the repository at this point in the history
…tainer-attr

✨ Add new option `label_container_attr` for SwitchType
  • Loading branch information
ker0x authored Apr 4, 2024
2 parents 200cd0c + 2c765fa commit d6473b5
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 15 deletions.
4 changes: 4 additions & 0 deletions docs/theme_customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Here is a list of all available class block:
* class_label
* class_input_radio_label
* class_input_switch_label
* class_input_switch_label_container
* Input
* class_input_text
* class_input_range
Expand All @@ -69,5 +70,8 @@ Here is a list of all available class block:
* Error
* class_label_error
* class_input_radio_label_error
* class_input_switch_label_error
* class_input_error
* class_text_error
* Disabled
* class_input_disabled
19 changes: 19 additions & 0 deletions src/Form/Type/SwitchType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,28 @@

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class SwitchType extends AbstractType
{
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars = array_replace($view->vars, [
'label_container_attr' => $options['label_container_attr'],
]);
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'label_container_attr' => [],
]);

$resolver->setAllowedTypes('label_container_attr', 'array');
}

public function getParent(): ?string
{
return CheckboxType::class;
Expand Down
38 changes: 24 additions & 14 deletions templates/form/default.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
{%- set attr = attr|merge({class: attr.class|default('flex')|trim}) -%}
{%- set attr = attr|merge({'class': attr.class|default('flex')|trim}) -%}
{%- set attr_class_error = '' -%}
{%- if not valid -%}
{%- set attr_class_error = ' ' ~ block('class_input_error') -%}
Expand All @@ -102,7 +102,7 @@
{%- if widget == 'single_text' -%}
{{ block('form_widget_simple') }}
{%- else -%}
{%- set attr = attr|merge({class: attr.class|default('flex')|trim}) -%}
{%- set attr = attr|merge({'class': attr.class|default('flex')|trim}) -%}
{%- set attr_class_error = '' -%}
{%- if not valid -%}
{%- set attr_class_error = ' ' ~ block('class_input_error') -%}
Expand All @@ -122,12 +122,12 @@
{%- endblock time_widget -%}

{%- block button_widget -%}
{%- set attr = attr|merge({class: (attr.class|default(block('class_button')))|trim}) -%}
{%- set attr = attr|merge({'class': (attr.class|default(block('class_button')))|trim}) -%}
{{- parent() -}}
{%- endblock button_widget %}

{%- block submit_widget -%}
{%- set attr = attr|merge({class: (attr.class|default(block('class_submit')))|trim}) -%}
{%- set attr = attr|merge({'class': (attr.class|default(block('class_submit')))|trim}) -%}
{{- parent() -}}
{%- endblock submit_widget %}

Expand All @@ -136,7 +136,7 @@
{%- block form_label -%}
{% if label is not same as(false) -%}
{%- set label_attr_class = (valid ? block('class_label') : block('class_label_error')) ~ ' ' ~ label_attr.class|default('') -%}
{%- set label_attr = label_attr|merge({class: label_attr_class|trim|tailwind_merge}) -%}
{%- set label_attr = label_attr|merge({'class': label_attr_class|trim|tailwind_merge}) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif -%}
Expand Down Expand Up @@ -182,16 +182,18 @@
{%- if checked and form.parent.vars.valid == false -%}
{%- set valid = false -%}
{%- endif -%}
{%- set label_attr_class = (valid ? block('class_input_radio_label') : block('class_input_radio_label_error')) ~ ' ' ~ label_attr.class|default('') -%}
{%- set label_attr = label_attr|merge({class: block('class_input_switch_label')}) -%}
{%- set label_attr_class = (valid ? block('class_input_switch_label') : block('class_input_switch_label_error')) ~ ' ' ~ label_attr.class|default('') -%}
{%- set label_container_attr_class = block('class_input_switch_label_container') ~ ' ' ~ label_container_attr.class|default('') -%}
{%- set label_attr = label_attr|merge({'class': label_attr_class|trim|tailwind_merge}) -%}
{%- set label_container_attr = label_container_attr|merge({'class': label_container_attr_class|trim|tailwind_merge}) -%}
{%- if not compound -%}
{%- set label_attr = label_attr|merge({'for': id}) -%}
{%- set label_container_attr = label_container_attr|merge({'for': id}) -%}
{%- endif -%}
<label{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}>
<label{% with { attr: label_container_attr } %}{{ block('attributes') }}{% endwith %}>
{{ widget|raw }}
<div class="{{ block('class_input_switch') }}"></div>
{%- if label is not same as(false) -%}
<span class="{{ label_attr_class|trim }}">
<span{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}>
{{- block('form_label_content') -}}
</span>
{%- endif -%}
Expand All @@ -204,7 +206,7 @@
{% block form_help -%}
{%- if help is not empty -%}
{%- set help_attr_class = (block('class_help_text') ~ ' '~ help_attr.class|default(''))|trim -%}
{%- set help_attr = help_attr|merge({class: help_attr_class}) -%}
{%- set help_attr = help_attr|merge({'class': help_attr_class}) -%}
<p id="{{ id }}_help"{% with { attr: help_attr } %}{{ block('attributes') }}{% endwith %}>
{{- block('form_help_content') -}}
</p>
Expand Down Expand Up @@ -247,7 +249,7 @@
{%- if disabled %}
{%- set attr_class = attr_class ~ ' ' ~ block('class_input_disabled') -%}
{% endif -%}
{%- set attr = attr|merge({class: attr_class|trim|tailwind_merge}) -%}
{%- set attr = attr|merge({'class': attr_class|trim|tailwind_merge}) -%}
{{ parent() }}
{%- endblock widget_attributes -%}

Expand All @@ -262,9 +264,13 @@
{%- endblock class_input_radio_label %}

{% block class_input_switch_label -%}
relative inline-flex items-center cursor-pointer
{{ block('class_input_radio_label') }}
{%- endblock class_input_switch_label %}

{% block class_input_switch_label_container -%}
relative inline-flex items-center cursor-pointer
{%- endblock class_input_switch_label_container %}

{% block class_input_text -%}
text-gray-900 bg-gray-50 rounded-lg text-sm block w-full p-2.5 border border-gray-300 focus:z-10 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500
{%- endblock class_input_text %}
Expand All @@ -286,7 +292,7 @@
{%- endblock class_input_checkbox %}

{% block class_input_switch -%}
w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-2 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 dark:border-gray-600 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600
relative w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-2 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 dark:border-gray-600 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600
{%- endblock class_input_switch %}

{% block class_select -%}
Expand Down Expand Up @@ -341,6 +347,10 @@
ml-2 text-sm font-medium text-red-600 dark:text-red-500
{%- endblock class_input_radio_label_error %}

{% block class_input_switch_label_error -%}
{{ block('class_input_radio_label_error') }}
{%- endblock class_input_switch_label_error %}

{% block class_input_error -%}
bg-red-50 border-red-500 text-red-900 placeholder-red-700 dark:bg-red-100 dark:border-red-500 dark:text-red-500 dark:placeholder-red-500 focus:z-10 focus:ring-red-500 focus:border-red-500 dark:focus:ring-red-500 dark:focus:border-red-500
{%- endblock class_input_error %}
Expand Down
38 changes: 37 additions & 1 deletion tests/FormLayout/SwitchLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace TalesFromADev\FlowbiteBundle\Tests\FormLayout;

use Symfony\Component\Form\FormError;
use TalesFromADev\FlowbiteBundle\Form\Type\SwitchType;
use TalesFromADev\FlowbiteBundle\Tests\AbstractFlowbiteLayoutTestCase;

Expand All @@ -25,12 +26,47 @@ public function testSwitch(): void
[@class="sr-only peer"]
[@value="1"]
/following-sibling::div
[@class="w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-2 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 dark:border-gray-600 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[\'\'] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"]
[@class="relative w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-2 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 dark:border-gray-600 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[\'\'] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"]
/following-sibling::span
[@class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"]
[.="[trans]Name[/trans]"]
]
'
);
}

public function testSwitchLabelContainerAttr(): void
{
$form = $this->factory->createNamed('name', SwitchType::class, false, [
'label_container_attr' => [
'class' => 'foo bar',
],
]);

$this->assertWidgetMatchesXpath($form->createView(), [],
'/label
[@class="relative inline-flex items-center cursor-pointer foo bar"]
[@for="name"]
'
);
}

public function testSwitchLabelError(): void
{
$form = $this->factory->createNamed('name', SwitchType::class);
$form->addError(new FormError('[trans]Error message[/trans]'));
$form->submit([]);

$this->assertWidgetMatchesXpath($form->createView(), [],
'/label
[@class="relative inline-flex items-center cursor-pointer"]
[@for="name"]
[
./span
[@class="ml-2 text-sm font-medium text-red-600 dark:text-red-500"]
[.="[trans]Name[/trans]"]
]
'
);
}
}

0 comments on commit d6473b5

Please sign in to comment.