diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 54b038b..8226541 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -21,6 +21,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 @@ -563,7 +564,13 @@ function template_preprocess_datetime_wrapper(&$variables) { $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; @@ -576,6 +583,45 @@ 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); + } + if (!empty($element['#description'])) { + $description_attributes = array( + 'class' => 'description', + 'id' => $element['#attributes']['aria-describedby'], + ); + $variables['description']['attributes'] = new Attribute($description_attributes); + $variables['description']['content'] = $element['#description']; + } +} + +/** * Prepares variables for links templates. * * Default template: links.html.twig. @@ -1721,6 +1767,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/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php index 2887d37..4a23ed2 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_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 1fc1d60..ede9244 100644 --- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php @@ -251,6 +251,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 b68da65..eb48062 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 + */ +#} + + {% if legend.title is not empty or required -%} + {# Always wrap fieldset legends in a SPAN for CSS positioning. #} + {{ legend.title }}{{ required }} + {%- endif %} +
+ {{ content }} + {% if description.content %} + {{ description.content }}
+ {% endif %} + + 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 }} +{{ description }} diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig index b67ec85..1fff1ef 100644 --- a/core/modules/system/templates/fieldset.html.twig +++ b/core/modules/system/templates/fieldset.html.twig @@ -16,6 +16,7 @@ * - children: The rendered child elements of the fieldset. * - prefix: The content to add before the fieldset children. * - suffix: The content to add after the fieldset children. + * - content: The form element to be output. * * @see template_preprocess_fieldset() * @@ -52,6 +53,7 @@ {{ prefix }} {% endif %} {{ children }} + {{ content }} {% if suffix %} {{ suffix }} {% endif %} diff --git a/core/themes/stable/templates/form/datetime-fieldset-wrapper.html.twig b/core/themes/stable/templates/form/datetime-fieldset-wrapper.html.twig new file mode 100644 index 0000000..91cc75f --- /dev/null +++ b/core/themes/stable/templates/form/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 + */ +#} + + {% if legend.title is not empty or required -%} + {# Always wrap fieldset legends in a SPAN for CSS positioning. #} + {{ legend.title }}{{ required }} + {%- endif %} +
+ {{ content }} + {% if description.content %} + {{ description.content }}
+ {% endif %} + +