Skip to content
Snippets Groups Projects
Commit 3db81375 authored by Gildas DELEPINE's avatar Gildas DELEPINE Committed by Florent Torregrosa
Browse files

Issue #3292739 by b-haslag, Grimreaper, gidel: Update description and label...

Issue #3292739 by b-haslag, Grimreaper, gidel: Update description and label classes for Bootstrap 5. Handle form-control.
parent 4ad15492
No related branches found
No related tags found
1 merge request!40Issue #3292739: Bootstrap 5: Form handling
<?php
declare(strict_types = 1);
namespace Drupal\ui_suite_bootstrap\HookHandler;
use Drupal\ui_suite_bootstrap\Utility\Variables;
/**
* Pre-processes variables for the "input" theme hook.
*/
class PreprocessInput {
/**
* The types of elements to not receive the "form-control" class.
*
* @var array
*/
protected array $ignoreFormControlTypes = [
'checkbox',
'hidden',
'radio',
];
/**
* The Variables object.
*
* @var \Drupal\ui_suite_bootstrap\Utility\Variables
*/
protected $variables;
/**
* An element object provided in the variables array, may not be set.
*
* @var \Drupal\bootstrap\Utility\Element|false
*/
protected $element;
/**
* {@inheritdoc}
*/
public function preprocess(array &$variables): void {
if (!isset($variables['element'])) {
return;
}
$this->variables = Variables::create($variables);
$this->element = $this->variables->element;
// Form control.
// @see https://getbootstrap.com/docs/5.2/forms/form-control
if ($this->element
&& !$this->element->isButton()
&& !$this->element->isType($this->ignoreFormControlTypes)
) {
if (!$this->element->hasClass('form-control-plaintext')) {
$this->variables->addClass('form-control');
if ($this->element->isType('color')) {
$this->variables->addClass('form-control-color');
}
}
}
}
}
...@@ -4,29 +4,26 @@ declare(strict_types = 1); ...@@ -4,29 +4,26 @@ declare(strict_types = 1);
namespace Drupal\ui_suite_bootstrap\HookHandler; namespace Drupal\ui_suite_bootstrap\HookHandler;
use Drupal\ui_suite_bootstrap\Utility\Variables;
/** /**
* Add theme suggestions. * Add theme suggestions.
*/ */
class ThemeSuggestionsAlter { class ThemeSuggestionsAlter {
/** /**
* The types of elements to ignore for the "input__form_control" suggestion. * The Variables object.
*
* @var \Drupal\ui_suite_bootstrap\Utility\Variables
*/ */
public const IGNORE_FORM_CONTROL_TYPES = [ protected $variables;
'checkbox',
'hidden',
'radio',
];
/** /**
* The form element types to be themed like buttons. * An element object provided in the variables array, may not be set.
*
* @var \Drupal\bootstrap\Utility\Element|false
*/ */
public const BUTTON_TYPES = [ protected $element;
'button',
'submit',
'reset',
'image_button',
];
/** /**
* Theme search block form. * Theme search block form.
...@@ -37,82 +34,16 @@ class ThemeSuggestionsAlter { ...@@ -37,82 +34,16 @@ class ThemeSuggestionsAlter {
* The theme variables. * The theme variables.
*/ */
public function input(array &$suggestions, array $variables): void { public function input(array &$suggestions, array $variables): void {
// @todo Create helper to manipulate render arrays. $this->variables = Variables::create($variables);
if ($this->isButton($variables['element'])) { $this->element = $this->variables->element;
if ($this->element && $this->element->isButton()) {
$hook = 'input__button'; $hook = 'input__button';
if ($this->isSplit($variables['element'])) { if ($this->element->getProperty('split')) {
$hook .= '__split'; $hook .= '__split';
} }
$suggestions[] = $hook; $suggestions[] = $hook;
} }
elseif (!$this->isType($variables['element'], self::IGNORE_FORM_CONTROL_TYPES)) {
$suggestions[] = 'input__form_control';
}
}
/**
* Check if element is of type button.
*
* @param array $element
* The render element to check.
*
* @return bool
* TRUE if element is of type button. FALSE otherwise.
*/
protected function isButton(array $element): bool {
return !empty($element['#is_button']) || $this->isType($element, self::BUTTON_TYPES) || $this->hasClass($element, 'btn');
}
/**
* Check if element has split property.
*
* @param array $element
* The render element to check.
*
* @return bool
* TRUE if element has split property. FALSE otherwise.
*/
protected function isSplit(array $element): bool {
if (isset($element['#split']) && $element['#split']) {
return TRUE;
}
return FALSE;
}
/**
* Check if element's type is among the types.
*
* @param array $element
* The render element to check.
* @param array $types
* The types to check.
*
* @return bool
* TRUE if element's type is among the types. FALSE otherwise.
*/
protected function isType(array $element, array $types): bool {
if (isset($element['#type']) && \in_array($element['#type'], $types, TRUE)) {
return TRUE;
}
return FALSE;
}
/**
* Check if element has class.
*
* @param array $element
* The render element to check.
* @param string $class
* The class to check.
*
* @return bool
* TRUE if has class. FALSE otherwise.
*/
protected function hasClass(array $element, string $class): bool {
if (isset($element['#attributes']['class']) && \in_array($class, $element['#attributes']['class'], TRUE)) {
return TRUE;
}
return FALSE;
} }
} }
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#} #}
{%- {%-
set classes = [ set classes = [
'control-label', 'form-label',
title_display == 'after' ? 'option', title_display == 'after' ? 'option',
title_display == 'invisible' and not (is_checkbox or is_radio) ? 'visually-hidden', title_display == 'invisible' and not (is_checkbox or is_radio) ? 'visually-hidden',
required ? 'js-form-required', required ? 'js-form-required',
......
...@@ -58,15 +58,15 @@ ...@@ -58,15 +58,15 @@
title_display not in ['after', 'before'] ? 'form-no-label', title_display not in ['after', 'before'] ? 'form-no-label',
disabled == 'disabled' ? 'form-disabled', disabled == 'disabled' ? 'form-disabled',
is_form_group ? 'form-group', is_form_group ? 'form-group',
is_radio ? 'radio', (is_radio or is_checkbox) ? 'form-check',
is_checkbox ? 'checkbox',
is_autocomplete ? 'form-autocomplete', is_autocomplete ? 'form-autocomplete',
has_error ? 'error has-error' has_error ? 'error has-error',
] floating_label ? 'form-floating'
]
%}{% %}{%
set description_classes = [ set description_classes = [
'description', 'description',
'alert-info', 'form-text',
description_display == 'invisible' ? 'visually-hidden', description_display == 'invisible' ? 'visually-hidden',
] ]
%} %}
......
{% extends "input.html.twig" %}
{#
/**
* @file
* Default theme implementation for an 'input__textfield' #type form element.
*
* Available variables:
* - attributes: A list of HTML attributes for the input element.
* - children: Optional additional rendered elements.
* - icon: An icon.
* - input_group: Flag to display as an input group.
* - icon_position: Where an icon should be displayed.
* - prefix: Markup to display before the input element.
* - suffix: Markup to display after the input element.
* - type: The type of input.
*
* @ingroup templates
*
* @see \Drupal\bootstrap\Plugin\Preprocess\Input
* @see template_preprocess_input()
*/
#}
{% spaceless %}
{%
set classes = [
'form-control',
]
%}
{% block input %}
<input{{ attributes.addClass(classes) }} />
{% endblock %}
{% endspaceless %}
...@@ -29,7 +29,11 @@ ...@@ -29,7 +29,11 @@
{% endif %} {% endif %}
{% block input %} {% block input %}
<input{{ attributes }} /> {#
Core puts a "form-text" class on input. In Bootstrap 5, this class is for
the description of the form element.
#}
<input{{ attributes.removeClass('form-text') }} />
{% endblock %} {% endblock %}
{% if suffix %} {% if suffix %}
......
...@@ -9,6 +9,7 @@ declare(strict_types = 1); ...@@ -9,6 +9,7 @@ declare(strict_types = 1);
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\ui_suite_bootstrap\HookHandler\FormSearchBlockFormAlter; use Drupal\ui_suite_bootstrap\HookHandler\FormSearchBlockFormAlter;
use Drupal\ui_suite_bootstrap\HookHandler\PreprocessInput;
use Drupal\ui_suite_bootstrap\HookHandler\PreprocessPage; use Drupal\ui_suite_bootstrap\HookHandler\PreprocessPage;
use Drupal\ui_suite_bootstrap\HookHandler\PreprocessPatternAccordion; use Drupal\ui_suite_bootstrap\HookHandler\PreprocessPatternAccordion;
use Drupal\ui_suite_bootstrap\HookHandler\PreprocessPatternAccordionItem; use Drupal\ui_suite_bootstrap\HookHandler\PreprocessPatternAccordionItem;
...@@ -162,3 +163,13 @@ function ui_suite_bootstrap_theme_suggestions_input_alter(array &$suggestions, a ...@@ -162,3 +163,13 @@ function ui_suite_bootstrap_theme_suggestions_input_alter(array &$suggestions, a
->getInstanceFromDefinition(ThemeSuggestionsAlter::class); ->getInstanceFromDefinition(ThemeSuggestionsAlter::class);
$instance->input($suggestions, $variables); $instance->input($suggestions, $variables);
} }
/**
* Implements hook_preprocess_HOOK() for 'input'.
*/
function ui_suite_bootstrap_preprocess_input(array &$variables): void {
/** @var \Drupal\ui_suite_bootstrap\HookHandler\PreprocessInput $instance */
$instance = \Drupal::service('class_resolver')
->getInstanceFromDefinition(PreprocessInput::class);
$instance->preprocess($variables);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment