diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 9b89250..084fe5c 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -24,6 +24,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Render\Element; use Drupal\Core\Render\Markup; +use Drupal\Component\Utility\Xss; /** * @defgroup content_flags Content markers @@ -569,15 +570,17 @@ function template_preprocess_datetime_form(&$variables) { function template_preprocess_datetime_wrapper(&$variables) { $element = $variables['element']; - if (!empty($element['#title'])) { - $variables['title'] = $element['#title']; - } - // Suppress error messages. $variables['errors'] = NULL; if (!empty($element['#description'])) { + // Add aria-describedby attribute to title tag for screen readers. $variables['description'] = $element['#description']; + $variables['attributes']['class'][] = 'description'; + // Associate the description with the aria-describedby attribute. + $variables['attributes']['id'] = $variables['attributes']['aria-describedby']; + // Remove aria-describedby attribute as it shouldn't be visible here. + unset($variables['attributes']['aria-describedby']); } $variables['required'] = FALSE; @@ -590,6 +593,37 @@ function template_preprocess_datetime_wrapper(&$variables) { } /** + * Prepares variables for datetime fieldset form wrapper templates. + * + * Default template: datetime-fieldset-wrapper.html.twig. + * + * @param array $variables + * An associative array containing: + * - element: An associative array containing the properties of the element. + * Properties used: #attributes, ,#content, #description, #id, #title, + * #required. + */ +function template_preprocess_datetime_fieldset_wrapper(&$variables) { + $element = $variables['element']; + $variables['content'] = $element['#children']; + $variables['attributes'] = $element['#attributes']; + $variables['attributes']['class'][] = 'form-item'; + $legend_attributes = array(); + if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') { + $legend_attributes['class'][] = 'visually-hidden'; + } + $variables['legend']['attributes'] = new Attribute($legend_attributes); + if (!empty($element['#title'])) { + $variables['legend']['title'] = Xss::filterAdmin($element['#title']); + } + $legend_span_attributes = array('class' => array('fieldset-legend')); + if (!empty($element['#required'])) { + $legend_span_attributes['class'][] = 'form-required'; + $variables['legend_span']['attributes'] = new Attribute($legend_span_attributes); + } +} + +/** * Prepares variables for links templates. * * Default template: links.html.twig. @@ -1736,6 +1770,10 @@ function drupal_common_theme() { 'datetime_wrapper' => array( 'render element' => 'element', ), + 'datetime_fieldset_wrapper' => array( + 'template' => 'datetime-fieldset-wrapper', + 'render element' => 'element', + ), 'status_messages' => array( 'variables' => ['status_headings' => [], 'message_list' => NULL], ), diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php index 44a3949..0f5377c 100644 --- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php +++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php @@ -257,7 +257,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state $element['date'] = array( '#type' => 'date', '#title' => t('Date'), - '#title_display' => 'invisible', + '#title_display' => 'before', '#value' => $date_value, '#attributes' => $element['#attributes'] + $extra_attributes, '#required' => $element['#required'], @@ -290,7 +290,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state $element['time'] = array( '#type' => 'date', '#title' => t('Time'), - '#title_display' => 'invisible', + '#title_display' => 'before', '#value' => $time_value, '#attributes' => $element['#attributes'] + $extra_attributes, '#required' => $element['#required'], diff --git a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php index 89381ab..e9f6e08 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php +++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php @@ -64,6 +64,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen case DateTimeItem::DATETIME_TYPE_DATE: $date_type = 'date'; $time_type = 'none'; + $element['#theme_wrappers'][] = 'datetime_fieldset_wrapper'; $date_format = $this->dateStorage->load('html_date')->getPattern(); $time_format = ''; break; @@ -71,6 +72,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen default: $date_type = 'date'; $time_type = 'time'; + $element['#theme_wrappers'][] = 'datetime_fieldset_wrapper'; $date_format = $this->dateStorage->load('html_date')->getPattern(); $time_format = $this->dateStorage->load('html_time')->getPattern(); break; diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php index ce598bf..9e6a776 100644 --- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php @@ -297,6 +297,7 @@ function testDatetimeField() { $this->drupalGet('entity_test/add'); $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.'); + $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/fieldset/legend/span[contains(@class, "form-required")]', TRUE, 'Required markup found'); // Build up a date in the UTC timezone. $value = '2012-12-31 00:00:00'; diff --git a/core/modules/system/css/components/container-inline.module.css b/core/modules/system/css/components/container-inline.module.css index ba99a36..5533e8a 100644 --- a/core/modules/system/css/components/container-inline.module.css +++ b/core/modules/system/css/components/container-inline.module.css @@ -11,3 +11,6 @@ .container-inline .details-wrapper { display: block; } +.container-inline .description { + display: block; +} diff --git a/core/modules/system/templates/datetime-fieldset-wrapper.html.twig b/core/modules/system/templates/datetime-fieldset-wrapper.html.twig new file mode 100644 index 0000000..91cc75f --- /dev/null +++ b/core/modules/system/templates/datetime-fieldset-wrapper.html.twig @@ -0,0 +1,34 @@ +{# +/** + * @file + * Default theme implementation of a datetime fieldset form wrapper. + * + * Available variables: + * - attributes: HTML attributes for the fieldset element. + * - required: The required marker or empty if the associated fieldset is + * not required. + * - legend: The legend element containing the following properties: + * - title: Title of the fieldset, intended for use as the text of the legend. + * - attributes: HTML attributes to apply to the legend. + * - description: The description element containing the following properties: + * - content: The description content of the fieldset. + * - attributes: HTML attributes to apply to the description container. + * - content: The form element to be output. + * + * @see template_preprocess_datetime_fieldset_wrapper() + * + * @ingroup themeable + */ +#} +
diff --git a/core/modules/system/templates/datetime-wrapper.html.twig b/core/modules/system/templates/datetime-wrapper.html.twig index 8430baa..7036633 100644 --- a/core/modules/system/templates/datetime-wrapper.html.twig +++ b/core/modules/system/templates/datetime-wrapper.html.twig @@ -8,6 +8,7 @@ * - title: The title of the form element. * - title_attributes: HTML attributes for the title wrapper. * - description: Description text for the form element. + * - attributes: Attributes for the description field. * - required: An indicator for whether the associated form element is required. * * @see template_preprocess_datetime_wrapper() @@ -30,4 +31,4 @@ {{ errors }} {% endif %} -{{ description }} +