diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php index dd7110f1ede6c998b5f33de076f6637eecf16f69..9cb51a0598e8e6f88a75f204135a996794b8b540 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php @@ -48,7 +48,7 @@ public function testFrontAndRecipesPagesAuthenticated(): void { $expected = [ 'ScriptCount' => 2, - 'ScriptBytes' => 249200, + 'ScriptBytes' => 249700, 'StylesheetCount' => 6, ]; $this->assertMetrics($expected, $performance_data); diff --git a/core/profiles/demo_umami/themes/umami/css/components/layout_builder/layout-builder.css b/core/profiles/demo_umami/themes/umami/css/components/layout_builder/layout-builder.css index 754d7d7c0f92a624a74fcb2559370a4e9c8797ff..556ec078339ee8db045a0c0d99174ddab9b6dea1 100644 --- a/core/profiles/demo_umami/themes/umami/css/components/layout_builder/layout-builder.css +++ b/core/profiles/demo_umami/themes/umami/css/components/layout_builder/layout-builder.css @@ -6,9 +6,9 @@ .layout-builder__message .messages { background-image: none; } -.layout-builder__message--defaults .messages__content { - --umami-message-icon: url("../../../../../../../misc/icons/73b355/globe.svg"); +.layout-builder__message--defaults .messages { + --umami-message-icon: url("/core/misc/icons/73b355/globe.svg"); } -.layout-builder__message--overrides .messages__content { - --umami-message-icon: url("../../../../../../../misc/icons/73b355/location.svg"); +.layout-builder__message--overrides .messages { + --umami-message-icon: url("/core/misc/icons/73b355/location.svg"); } diff --git a/core/profiles/demo_umami/themes/umami/css/components/messages/messages.css b/core/profiles/demo_umami/themes/umami/css/components/messages/messages.css index df80f509f0c7a61a450da3a2cb9224d74e1a3fa3..2e90717892b5eb71eec549d910ecf54cd3e98da4 100644 --- a/core/profiles/demo_umami/themes/umami/css/components/messages/messages.css +++ b/core/profiles/demo_umami/themes/umami/css/components/messages/messages.css @@ -9,16 +9,6 @@ color: inherit; overflow-wrap: break-word; } -.messages__content { - padding-inline-start: 24px; - background-image: var(--umami-message-icon); - background-repeat: no-repeat; - background-position-x: left; - background-position-y: center; -} -[dir="rtl"] .messages__content { - background-position-x: right; -} .messages--status { --umami-message-icon: url(/core/misc/icons/73b355/check.svg); @@ -44,14 +34,32 @@ color: #cc2a00; } .messages__list { + display: grid; + gap: 0.769em; margin: 0; padding: 0; list-style: none; } -.messages__item + .messages__item { - margin-top: 0.769em; -} .messages__wrapper { display: grid; gap: 1.538em; } +drupal-umami-messages::part(heading) { + position: absolute !important; + overflow: hidden; + clip: rect(1px, 1px, 1px, 1px); + width: 1px; + height: 1px; + word-wrap: normal; +} +drupal-umami-messages::part(content) { + display: flex; + align-items: center; + gap: 0.5rem; +} +drupal-umami-messages::part(icon) { + flex: 0 0 1rem; + width: 1rem; + height: 1rem; + background-image: var(--umami-message-icon); +} diff --git a/core/profiles/demo_umami/themes/umami/js/components/messages/messages.js b/core/profiles/demo_umami/themes/umami/js/components/messages/messages.js index 3df0790cb3c276610befd2470b3ddee3dc5644eb..2b3c8e7a61feda140102e1ce548ebab4f0be34fa 100644 --- a/core/profiles/demo_umami/themes/umami/js/components/messages/messages.js +++ b/core/profiles/demo_umami/themes/umami/js/components/messages/messages.js @@ -4,6 +4,20 @@ */ ((Drupal) => { + customElements.define( + 'drupal-umami-messages', + class extends HTMLElement { + constructor() { + super(); + const template = document.getElementById('umami-messages-template'); + const templateContent = template.content; + + const shadowRoot = this.attachShadow({ mode: 'open' }); + shadowRoot.appendChild(templateContent.cloneNode(true)); + } + }, + ); + /** * Overrides message theme function. * @@ -23,7 +37,7 @@ */ Drupal.theme.message = ({ text }, { type, id }) => { const messagesTypes = Drupal.Message.getMessageTypeLabels(); - const messageWrapper = document.createElement('div'); + const messageWrapper = document.createElement('drupal-umami-messages'); messageWrapper.setAttribute('class', `messages messages--${type}`); messageWrapper.setAttribute( @@ -34,14 +48,12 @@ messageWrapper.setAttribute('data-drupal-message-type', type); messageWrapper.innerHTML = ` - <div class="messages__content"> - <h2 class="visually-hidden"> - ${messagesTypes[type]} - </h2> - <span class="messages__item"> - ${text} - </span> - </div> + <span slot="title"> + ${messagesTypes[type]} + </span> + <span class="messages__item" slot="content"> + ${text} + </span> `; return messageWrapper; diff --git a/core/profiles/demo_umami/themes/umami/templates/classy/block/block--system-messages-block.html.twig b/core/profiles/demo_umami/themes/umami/templates/classy/block/block--system-messages-block.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..216888c61f24e7926314ed6522c4746df536c9d2 --- /dev/null +++ b/core/profiles/demo_umami/themes/umami/templates/classy/block/block--system-messages-block.html.twig @@ -0,0 +1,38 @@ +{# +/** + * @file + * Default theme implementation for the messages block. + * + * Removes wrapper elements from block so that empty block does not appear when + * there are no messages. + * + * Available variables: + * - content: The content of this block. + * + * @ingroup themeable + */ +#} +{{ content }} + +{# + The Umami theme is for demonstration only. + + Umami uses a web component for rendering messages. The component is + "<drupal-umami-messages>". + + This implementation is a trial only and should not be used on production + sites. + + @see https://www.drupal.org/project/drupal/issues/3476471 + @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components +#} + +<template id="umami-messages-template"> + <h2 part="heading"> + <slot name="title"></slot> + </h2> + <div part="content"> + <div part="icon"></div> + <slot name="content"></slot> + </div> +</template> diff --git a/core/profiles/demo_umami/themes/umami/templates/components/messages/status-messages.html.twig b/core/profiles/demo_umami/themes/umami/templates/components/messages/status-messages.html.twig index 8f2127521b5bfb0732c1e30fa523b67122979fc1..cc133482c0607349f4ad64eb9c33f93740312247 100644 --- a/core/profiles/demo_umami/themes/umami/templates/components/messages/status-messages.html.twig +++ b/core/profiles/demo_umami/themes/umami/templates/components/messages/status-messages.html.twig @@ -22,36 +22,30 @@ <div data-drupal-messages> <div class="messages__wrapper container"> {% block messages %} - {% for type, messages in message_list %} - {% - set classes = [ - 'messages', - 'messages--' ~ type, - ] - %} - <div - aria-label="{{ status_headings[type] }}" - {{ attributes.addClass(classes)|without('aria-label') }} - role={{ type == 'error' or type == 'warning' ? 'alert' : 'status' }} - > - <div class="messages__content"> + {% for type, messages in message_list %} + {% + set classes = [ + 'messages', + 'messages--' ~ type, + ] + %} + <drupal-umami-messages aria-label="{{ status_headings[type] }}" {{ attributes.addClass(classes)|without('aria-label') }} role={{ type == 'error' or type == 'warning' ? 'alert' : 'status' }}> {% if status_headings[type] %} - <h2 class="visually-hidden">{{ status_headings[type] }}</h2> + <span slot="title">{{ status_headings[type] }}</span> {% endif %} - {% if messages|length > 1 %} - <ul class="messages__list"> + {% if messages|length > 0 %} + <ul class="messages__list" slot="content"> {% for message in messages %} <li class="messages__item">{{ message }}</li> {% endfor %} </ul> {% else %} - <span class="messages__item">{{ messages|first }}</span> + <span class="messages__item" slot="content">{{ messages|first }}</span> {% endif %} - </div> - </div> - {# Remove type specific classes. #} - {% set attributes = attributes.removeClass(classes) %} - {% endfor %} + </drupal-umami-messages> + {# Remove type specific classes. #} + {% set attributes = attributes.removeClass(classes) %} + {% endfor %} {% endblock messages %} </div> </div>