@ecl/site-header 5.0.0-alpha.1 → 5.0.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,17 +2,18 @@
2
2
 
3
3
  {#
4
4
  Parameters:
5
- - "icon_path" (string) (default: ''): URL to icons file
6
5
  - "banner_top" (object): Object of type link (link : { label, path })
7
6
  - "logged" (boolean): Whether the user is logged in or not
8
7
  - "menu" (associative array): Menu content, if any. Uses ECL Menu structure
9
8
  - "mega_menu" (associative array): Menu content, if any. Uses ECL Mega Menu structure
10
9
  - "site_name" (string) Site name
10
+ - "site_name_mobile_only" (boolean): Whether the site name should be hidden on desktop or not
11
11
  - "cta_link": (optional) (default: {}): Call to action link compatible with ECL Link component structure
12
12
  - "logo" (associative array) (default: predefined structure): Logo image settings. format:
13
13
  {
14
14
  "title": (string) (default: ''): Logo title attribute.
15
15
  "alt": (string) (default: ''): Logo alt attribute.
16
+ "breakpoint": (string) (default: 's') Breakpoint where to switch the logo displayed. Expected value in EU is "l"
16
17
  "href": (string) (default: ''): Logo URL.
17
18
  "src_desktop": (string) (default: ''): Desktop logo image file path
18
19
  "src_mobile": (string) (default: ''): Mobile logo image file path for EU only
@@ -48,6 +49,22 @@
48
49
  ],
49
50
  },
50
51
  },
52
+ - "custom_action" (associative array) (default: {}): optional custom link with optional popover, e.g.:
53
+ {
54
+ "link": (object) (default: predefined structure) predefined structure for the Link component
55
+ "icon" (associative array) OR (array) of associative arrays : format
56
+ {
57
+ name: (string) (default: ''),
58
+ extra_classes: (string) (default: 'ecl-link__icon'),
59
+ ...
60
+ }
61
+ "overlay": (object) – if defined, we display a popover; otherwise it’s a simple link
62
+ {
63
+ "title": (string) (default: '')
64
+ "close_label": (string) (default: '')
65
+ "content": (string)
66
+ }
67
+ }
51
68
  - "search_toggle" (associate array) (default: {}) format:
52
69
  {
53
70
  "label": (string) Label of the element
@@ -67,7 +84,7 @@
67
84
  "label_logged": (string) Label for the logged in users
68
85
  "href_logged": (string) Link to the logout form
69
86
  }
70
- - "search_form" (associative array) (default: predefined structure): EC Search Form component structure
87
+ - "search_form" (associative array) (default: predefined structure): ECL Search Form component structure
71
88
  - "notification" (object) (default: {}): Optional notification compatible with ECL Notification component structure
72
89
  - "extra_classes" (string) (default: '')
73
90
  - "extra_attributes" (array) (default: data-ecl-auto-init="SiteHeaderStandardised"): format: [
@@ -82,14 +99,15 @@
82
99
 
83
100
  {% set _logo = logo|default({}) %}
84
101
  {% set _language_selector = language_selector|default({}) %}
102
+ {% set _custom_action = custom_action|default({}) %}
85
103
  {% set _logged = logged|default(false) %}
86
104
  {% set _login_box = login_box|default({}) %}
87
105
  {% set _login_toggle = login_toggle|default({}) %}
88
106
  {% set _search_toggle = search_toggle|default({}) %}
89
- {% set _icon_path = icon_path|default('') %}
90
107
  {% set _menu = menu|default(false) %}
91
108
  {% set _mega_menu = mega_menu|default(false) %}
92
109
  {% set _site_name = site_name|default('') %}
110
+ {% set _site_name_mobile_only = site_name_mobile_only|default(false) %}
93
111
  {% set _cta_link = cta_link|default({}) %}
94
112
  {% set _notification = notification|default({}) %}
95
113
  {% set _extra_attributes = '' %}
@@ -167,7 +185,6 @@
167
185
  label: _search_button_label,
168
186
  icon: {
169
187
  name: 'search',
170
- path: _icon_path,
171
188
  size: 'fluid',
172
189
  },
173
190
  icon_position: 'before',
@@ -213,155 +230,224 @@
213
230
  {{ _extra_attributes|raw }}
214
231
  >
215
232
  <div class="ecl-site-header__inner">
216
- <div class="ecl-site-header__background">
217
- <div class="ecl-site-header__header">
218
- <div class="ecl-site-header__container ecl-container">
219
- <div class="ecl-site-header__top" data-ecl-site-header-top>
220
- {# Logo #}
221
- {% if _logo is not empty and _logo.src_desktop is not empty %}
222
- {% set _label %}
223
- {% set _picture = { sources: [{ src: _logo.src_desktop, media: 'l' }] } %}
224
- {% if _logo.src_mobile is defined and _logo.src_mobile is not empty %}
225
- {% set _picture = _picture|merge({
226
- img: {
227
- src: _logo.src_mobile,
228
- alt: _logo.alt,
229
- },
230
- }) %}
231
- {% else %}
232
- {% set _picture = _picture|merge({
233
- img: {
234
- src: _logo.src_desktop,
235
- alt: _logo.alt,
236
- },
237
- }) %}
238
- {% endif %}
239
- {% set image_classes = 'ecl-site-header__logo-image' %}
240
- {% set image_classes = image_classes ~ ' ecl-site-header__logo-image--' ~ _logo.size|default('l') %}
241
- {% include '@ecl/picture/picture.html.twig' with {
242
- picture: _picture,
243
- extra_classes: "ecl-site-header__picture",
244
- extra_image_classes: image_classes,
245
- extra_attributes: _logo.title is not empty ? [{ name: 'title', value: _logo.title }] : [],
246
- } only %}
247
- {% endset %}
248
- {% include '@ecl/link/link.html.twig' with {
249
- link: {
250
- path: _logo.path,
251
- label: _label,
252
- type: 'standalone'
253
- },
254
- extra_classes: 'ecl-site-header__logo-link'
233
+ <div class="ecl-site-header__header">
234
+ <div class="ecl-site-header__container ecl-container">
235
+ <div class="ecl-site-header__top" data-ecl-site-header-top>
236
+ {# Logo #}
237
+ {% if _logo is not empty and _logo.src_desktop is not empty %}
238
+ {% set _label %}
239
+ {% set _picture = { sources: [{ src: _logo.src_desktop, media: _logo.breakpoint|default('s') }] } %}
240
+ {% if _logo.src_mobile is defined and _logo.src_mobile is not empty %}
241
+ {% set _picture = _picture|merge({
242
+ img: {
243
+ src: _logo.src_mobile,
244
+ alt: _logo.alt,
245
+ },
246
+ }) %}
247
+ {% else %}
248
+ {% set _picture = _picture|merge({
249
+ img: {
250
+ src: _logo.src_desktop,
251
+ alt: _logo.alt,
252
+ },
253
+ }) %}
254
+ {% endif %}
255
+ {% set image_classes = 'ecl-site-header__logo-image' %}
256
+ {% set image_classes = image_classes ~ ' ecl-site-header__logo-image--' ~ _logo.size|default('l') %}
257
+ {% include '@ecl/picture/picture.html.twig' with {
258
+ picture: _picture,
259
+ extra_classes: "ecl-site-header__picture",
260
+ extra_image_classes: image_classes,
261
+ extra_attributes: _logo.title is not empty ? [{ name: 'title', value: _logo.title }] : [],
255
262
  } only %}
256
- {% endif %}
263
+ {% endset %}
264
+ {% include '@ecl/link/link.html.twig' with {
265
+ link: {
266
+ path: _logo.path,
267
+ label: _label,
268
+ type: 'standalone'
269
+ },
270
+ extra_classes: 'ecl-site-header__logo-link'
271
+ } only %}
272
+ {% endif %}
257
273
 
258
- {# Header actions #}
259
- <div class="ecl-site-header__action">
260
-
261
- {# Login #}
262
- {% if _login_toggle is not empty and _login_box is not empty %}
263
- <div class="ecl-site-header__login-container">
264
- {% if _logged %}
265
- <a
266
- class="ecl-button ecl-button--tertiary ecl-site-header__login-toggle"
267
- href="{{ _login_toggle.href_logged }}"
268
- aria-controls="{{ _login_box.id }}"
269
- data-ecl-login-toggle
270
- aria-expanded="false"
271
- >
272
- {% include '@ecl/icon/icon.html.twig' with {
273
- icon: {
274
- path: _icon_path,
275
- name: 'logged-in',
276
- size: 's'
277
- },
278
- as_image: true,
279
- extra_classes: 'ecl-site-header__icon',
280
- extra_accessibility: {
281
- title: login_toggle.label_logged,
282
- },
283
- } only %}
284
- {{- login_toggle.label_logged -}}
285
- </a>
286
- <div
287
- id="{{ _login_box.id }}"
288
- class="ecl-site-header__login-box"
289
- data-ecl-login-box
290
- >
291
- <p class="ecl-site-header__login-description">
292
- {{- _login_box.description -}}
293
- </p>
294
- <hr class="ecl-site-header__login-separator">
295
- {% include '@ecl/link/link.html.twig' with {
296
- link: {
297
- label: _login_box.label,
298
- path: _login_box.href,
299
- type: 'standalone',
300
- }
301
- } only %}
302
- </div>
274
+ {# Header actions #}
275
+ <div class="ecl-site-header__action">
276
+
277
+ {# Custom action #}
278
+ {% if _custom_action is not empty %}
279
+ <div class="ecl-site-header__custom-action" aria-live="polite">
280
+ {% set is_overlay = _custom_action.overlay is defined and _custom_action.overlay is not empty %}
281
+ {% set has_icon = _custom_action.icon is defined and _custom_action.icon is not empty %}
282
+
283
+ {% set link_extra_attributes = _custom_action.link.extra_attributes|default([]) %}
284
+ {% set link_extra_attributes = link_extra_attributes|merge([
285
+ { name: 'role', value: 'button' },
286
+ { name: 'data-ecl-custom-action', value: '' }
287
+ ]) %}
288
+ {% if is_overlay %}
289
+ {% set link_extra_attributes = link_extra_attributes|merge([
290
+ { name: 'aria-controls', value: 'custom-action-overlay' },
291
+ { name: 'aria-expanded', value: 'false' }
292
+ ]) %}
293
+ {% endif %}
294
+
295
+ {% if has_icon %}
296
+ {% set icon_extra_classes = _custom_action.icon.extra_classes|default('') %}
297
+ {% set icon_extra_classes = icon_extra_classes ~ ' ecl-site-header__icon' %}
298
+ {% set icon = _custom_action.icon|merge({
299
+ extra_classes: icon_extra_classes
300
+ }) %}
303
301
  {% else %}
304
- <a
305
- class="ecl-button ecl-button--tertiary ecl-site-header__login-toggle"
306
- href="{{ _login_toggle.href_not_logged }}"
307
- data-ecl-login-toggle
308
- >
309
- {% include '@ecl/icon/icon.html.twig' with {
310
- icon: {
311
- path: _icon_path,
312
- name: 'log-in',
313
- size: 's'
314
- },
315
- as_image: true,
316
- extra_classes: 'ecl-site-header__icon',
317
- extra_accessibility: {
318
- title: login_toggle.label_not_logged,
319
- },
320
- } only %}
321
- {{- login_toggle.label_not_logged -}}
322
- </a>
302
+ {% set icon = null %}
323
303
  {% endif %}
324
- </div>
325
- {% endif %}
326
304
 
327
- {# Language selector #}
328
- {% if _language_selector is not empty %}
329
- {% include '@ecl/site-header/site-header-language-switcher.html.twig' with {
330
- language_selector: _language_selector,
331
- icon_path: _icon_path,
332
- } only %}
333
- {% endif %}
305
+ {% set custom_action_link = {
306
+ link: _custom_action.link|merge({ type: "standalone" }),
307
+ icon: icon,
308
+ extra_attributes: link_extra_attributes,
309
+ extra_classes: (
310
+ _custom_action.link.extra_classes is defined and _custom_action.link.extra_classes is not empty
311
+ ? _custom_action.link.extra_classes ~ ' ecl-site-header__custom-action-toggle ecl-button ecl-button--tertiary'
312
+ : 'ecl-site-header__custom-action-toggle ecl-button ecl-button--tertiary'
313
+ )
314
+ } %}
315
+ {% include '@ecl/link/link.html.twig' with custom_action_link only %}
334
316
 
335
- {# Search form #}
336
- {% if _search_form is defined %}
337
- <div class="ecl-site-header__search-container" role="search">
338
- {% if _search_toggle is not empty %}
339
- <a
340
- class="ecl-button ecl-button--tertiary ecl-site-header__search-toggle"
341
- href="{{ _search_toggle.href }}"
342
- data-ecl-search-toggle="true"
343
- aria-controls="search-form-id"
344
- aria-expanded="false"
317
+ {% if _custom_action.overlay is defined and _custom_action.overlay is not empty %}
318
+ <div
319
+ class="ecl-site-header__custom-action-overlay"
320
+ id="custom-action-overlay"
321
+ hidden
322
+ data-ecl-custom-action-overlay
323
+ role="dialog"
324
+ aria-labelledby="custom-action-overlay-title"
345
325
  >
346
- {%- include '@ecl/icon/icon.html.twig' with {
326
+ <div class="ecl-site-header__custom-action-header">
327
+ <div class="ecl-site-header__custom-action-title" id="custom-action-overlay-title">
328
+ {{ _custom_action.overlay.title|default('') }}
329
+ </div>
330
+
331
+ {% if _custom_action.overlay.close is defined and _custom_action.overlay.close is not empty %}
332
+ {% include '@ecl/button/button.html.twig' with _custom_action.overlay.close|merge({
333
+ variant: 'tertiary',
334
+ extra_classes: 'ecl-site-header__custom-action-close',
335
+ extra_attributes: [{
336
+ name: 'data-ecl-custom-action-close',
337
+ }],
338
+ }) %}
339
+ {% endif %}
340
+ </div>
341
+ <div class="ecl-site-header__custom-action-content">
342
+ {{ _custom_action.overlay.content|default('')|raw }}
343
+ </div>
344
+ </div>
345
+ {% endif %}
346
+ </div>
347
+ {% endif %}
348
+
349
+ {# Login #}
350
+ {% if _login_toggle is not empty and _login_box is not empty %}
351
+ <div class="ecl-site-header__login-container">
352
+ {% if _logged %}
353
+ <a
354
+ class="ecl-button ecl-button--tertiary ecl-site-header__login-toggle"
355
+ href="{{ _login_toggle.href_logged }}"
356
+ aria-controls="{{ _login_box.id }}"
357
+ data-ecl-login-toggle
358
+ aria-expanded="false"
359
+ >
360
+ {% include '@ecl/icon/icon.html.twig' with {
347
361
  icon: {
348
- name: 'search',
349
- path: _icon_path,
350
- size: 's',
362
+ name: 'logged-in',
363
+ size: 's'
351
364
  },
352
365
  as_image: true,
353
366
  extra_classes: 'ecl-site-header__icon',
354
367
  extra_accessibility: {
355
- title: _search_toggle.label,
368
+ title: login_toggle.label_logged,
356
369
  },
357
- } only -%}
358
- {{- _search_toggle.label -}}
359
- </a>
360
- {% endif %}
361
- {% include '@ecl/search-form/search-form.html.twig' with _search_form only %}
370
+ } only %}
371
+ {{- login_toggle.label_logged -}}
372
+ </a>
373
+ <div
374
+ id="{{ _login_box.id }}"
375
+ class="ecl-site-header__login-box"
376
+ data-ecl-login-box
377
+ >
378
+ <p class="ecl-site-header__login-description">
379
+ {{- _login_box.description -}}
380
+ </p>
381
+ <hr class="ecl-site-header__login-separator">
382
+ {% include '@ecl/link/link.html.twig' with {
383
+ link: {
384
+ label: _login_box.label,
385
+ path: _login_box.href,
386
+ type: 'standalone',
387
+ }
388
+ } only %}
362
389
  </div>
390
+ {% else %}
391
+ <a
392
+ class="ecl-button ecl-button--tertiary ecl-site-header__login-toggle"
393
+ href="{{ _login_toggle.href_not_logged }}"
394
+ data-ecl-login-toggle
395
+ >
396
+ {% include '@ecl/icon/icon.html.twig' with {
397
+ icon: {
398
+ path: _icon_path,
399
+ name: 'log-in',
400
+ size: 's'
401
+ },
402
+ as_image: true,
403
+ extra_classes: 'ecl-site-header__icon',
404
+ extra_accessibility: {
405
+ title: login_toggle.label_not_logged,
406
+ },
407
+ } only %}
408
+ {{- login_toggle.label_not_logged -}}
409
+ </a>
363
410
  {% endif %}
364
411
  </div>
412
+ {% endif %}
413
+
414
+ {# Language selector #}
415
+ {% if _language_selector is not empty %}
416
+ {% include '@ecl/site-header/site-header-language-switcher.html.twig' with {
417
+ language_selector: _language_selector,
418
+ icon_path: _icon_path,
419
+ } only %}
420
+ {% endif %}
421
+
422
+ {# Search form #}
423
+ {% if _search_form is defined %}
424
+ <div class="ecl-site-header__search-container" role="search">
425
+ {% if _search_toggle is not empty %}
426
+ <a
427
+ class="ecl-button ecl-button--tertiary ecl-site-header__search-toggle"
428
+ href="{{ _search_toggle.href }}"
429
+ data-ecl-search-toggle="true"
430
+ aria-controls="search-form-id"
431
+ aria-expanded="false"
432
+ >
433
+ {%- include '@ecl/icon/icon.html.twig' with {
434
+ icon: {
435
+ name: 'search',
436
+ path: _icon_path,
437
+ size: 's',
438
+ },
439
+ as_image: true,
440
+ extra_classes: 'ecl-site-header__icon',
441
+ extra_accessibility: {
442
+ title: _search_toggle.label,
443
+ },
444
+ } only -%}
445
+ {{- _search_toggle.label -}}
446
+ </a>
447
+ {% endif %}
448
+ {% include '@ecl/search-form/search-form.html.twig' with _search_form only %}
449
+ </div>
450
+ {% endif %}
365
451
  </div>
366
452
  </div>
367
453
  </div>
@@ -387,7 +473,6 @@
387
473
  {%- if banner_top.link is defined and banner_top.link is not empty %}
388
474
  {% include '@ecl/link/link.html.twig' with banner_top|merge({
389
475
  link: banner_top.link|merge({ type: 'standalone', no_visited: true}),
390
- icon_path: _icon_path
391
476
  }) only %}
392
477
  {% else %}
393
478
  {{ banner_top }}
@@ -401,7 +486,13 @@
401
486
  <div class="ecl-site-header__banner">
402
487
  <div class="ecl-container">
403
488
  {% if _site_name is not empty %}
404
- <div class="ecl-site-header__site-name">{{ _site_name }}</div>
489
+ {% set _site_name_class = 'ecl-site-header__site-name' %}
490
+ {% if _site_name_mobile_only %}
491
+ {% set _site_name_class = _site_name_class ~ ' ecl-site-header__site-name--mobile-only' %}
492
+ {% endif %}
493
+ <div class="{{ _site_name_class }}">
494
+ {{- _site_name -}}
495
+ </div>
405
496
  {% endif %}
406
497
  {% if _cta_link is not empty and _cta_link.link is not empty %}
407
498
  {% include '@ecl/link/link.html.twig' with _cta_link|merge({
@@ -420,13 +511,11 @@
420
511
  {% if _menu is defined and _menu is not empty %}
421
512
  {% include '@ecl/menu/menu.html.twig' with _menu|merge({
422
513
  site_name: _site_name,
423
- icon_path: _icon_path,
424
514
  }) only %}
425
515
  {% endif %}
426
516
  {% if _mega_menu is defined and _mega_menu is not empty %}
427
517
  {% include '@ecl/mega-menu/mega-menu.html.twig' with _mega_menu|merge({
428
518
  site_name: _site_name,
429
- icon_path: _icon_path,
430
519
  }) only %}
431
520
  {% endif %}
432
521
  </header>