@ecl/site-header 5.0.0-alpha.2 → 5.0.0-alpha.21

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: 'xs', 415px) 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,228 @@
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('xs') }] } %}
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
+ {% set has_hidden_label = _custom_action.link.hide_label is defined and _custom_action.link.hide_label is not empty %}
283
+
284
+ {% set link_extra_attributes = _custom_action.link.extra_attributes|default([]) %}
285
+ {% set link_extra_attributes = link_extra_attributes|merge([
286
+ { name: 'role', value: 'button' },
287
+ { name: 'data-ecl-custom-action', value: '' }
288
+ ]) %}
289
+ {% if is_overlay %}
290
+ {% set link_extra_attributes = link_extra_attributes|merge([
291
+ { name: 'aria-controls', value: 'custom-action-overlay' },
292
+ { name: 'aria-expanded', value: 'false' }
293
+ ]) %}
294
+ {% endif %}
295
+
296
+ {% if has_icon %}
297
+ {% set icon = _custom_action.icon|merge({
298
+ extra_classes: (_custom_action.icon.extra_classes|default('')) ~ ' ecl-site-header__icon'
299
+ }) %}
303
300
  {% 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>
301
+ {% set icon = null %}
323
302
  {% endif %}
324
- </div>
325
- {% endif %}
326
303
 
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 %}
304
+ {% set base_classes = 'ecl-site-header__custom-action-toggle ecl-button ecl-button--tertiary ecl-button--neutral' %}
305
+ {% if has_icon and has_hidden_label %}
306
+ {% set base_classes = base_classes ~ ' ecl-button--icon-only' %}
307
+ {% endif %}
308
+ {% set user_classes = _custom_action.link.extra_classes|default('') %}
309
+ {% set full_classes = (user_classes ? user_classes ~ ' ' : '') ~ base_classes %}
310
+
311
+ {% set custom_action_link = {
312
+ link: _custom_action.link|merge({ type: 'standalone' }),
313
+ icon: icon,
314
+ extra_attributes: link_extra_attributes,
315
+ extra_classes: full_classes
316
+ } %}
334
317
 
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"
318
+ {% include '@ecl/link/link.html.twig' with custom_action_link only %}
319
+
320
+ {% if _custom_action.overlay is defined and _custom_action.overlay is not empty %}
321
+ <div
322
+ class="ecl-site-header__custom-action-overlay"
323
+ id="custom-action-overlay"
324
+ hidden
325
+ data-ecl-custom-action-overlay
326
+ role="dialog"
327
+ aria-labelledby="custom-action-overlay-title"
345
328
  >
346
- {%- include '@ecl/icon/icon.html.twig' with {
329
+ <div class="ecl-site-header__custom-action-header">
330
+ <div class="ecl-site-header__custom-action-title" id="custom-action-overlay-title">
331
+ {{ _custom_action.overlay.title|default('') }}
332
+ </div>
333
+
334
+ {% if _custom_action.overlay.close is defined and _custom_action.overlay.close is not empty %}
335
+ {% include '@ecl/button/button.html.twig' with _custom_action.overlay.close|merge({
336
+ variant: 'tertiary',
337
+ style: 'neutral',
338
+ extra_classes: 'ecl-site-header__custom-action-close',
339
+ extra_attributes: [{
340
+ name: 'data-ecl-custom-action-close',
341
+ }],
342
+ }) %}
343
+ {% endif %}
344
+ </div>
345
+ <div class="ecl-site-header__custom-action-content">
346
+ {{ _custom_action.overlay.content|default('')|raw }}
347
+ </div>
348
+ </div>
349
+ {% endif %}
350
+ </div>
351
+ {% endif %}
352
+
353
+ {# Login #}
354
+ {% if _login_toggle is not empty and _login_box is not empty %}
355
+ <div class="ecl-site-header__login-container">
356
+ {% if _logged %}
357
+ <a
358
+ class="ecl-button ecl-button--tertiary ecl-button--neutral ecl-site-header__login-toggle"
359
+ href="{{ _login_toggle.href_logged }}"
360
+ aria-controls="{{ _login_box.id }}"
361
+ data-ecl-login-toggle
362
+ aria-expanded="false"
363
+ >
364
+ {% include '@ecl/icon/icon.html.twig' with {
347
365
  icon: {
348
- name: 'search',
349
- path: _icon_path,
350
- size: 's',
366
+ name: 'logged-in',
367
+ size: 'm'
351
368
  },
352
369
  as_image: true,
353
370
  extra_classes: 'ecl-site-header__icon',
354
371
  extra_accessibility: {
355
- title: _search_toggle.label,
372
+ title: login_toggle.label_logged,
356
373
  },
357
- } only -%}
358
- {{- _search_toggle.label -}}
359
- </a>
360
- {% endif %}
361
- {% include '@ecl/search-form/search-form.html.twig' with _search_form only %}
374
+ } only %}
375
+ {{- login_toggle.label_logged -}}
376
+ </a>
377
+ <div
378
+ id="{{ _login_box.id }}"
379
+ class="ecl-site-header__login-box"
380
+ data-ecl-login-box
381
+ >
382
+ <p class="ecl-site-header__login-description">
383
+ {{- _login_box.description -}}
384
+ </p>
385
+ <hr class="ecl-site-header__login-separator">
386
+ {% include '@ecl/link/link.html.twig' with {
387
+ link: {
388
+ label: _login_box.label,
389
+ path: _login_box.href,
390
+ type: 'standalone',
391
+ }
392
+ } only %}
362
393
  </div>
394
+ {% else %}
395
+ <a
396
+ class="ecl-button ecl-button--tertiary ecl-button--neutral ecl-site-header__login-toggle"
397
+ href="{{ _login_toggle.href_not_logged }}"
398
+ data-ecl-login-toggle
399
+ >
400
+ {% include '@ecl/icon/icon.html.twig' with {
401
+ icon: {
402
+ path: _icon_path,
403
+ name: 'log-in',
404
+ size: 'm'
405
+ },
406
+ as_image: true,
407
+ extra_classes: 'ecl-site-header__icon',
408
+ extra_accessibility: {
409
+ title: login_toggle.label_not_logged,
410
+ },
411
+ } only %}
412
+ {{- login_toggle.label_not_logged -}}
413
+ </a>
363
414
  {% endif %}
364
415
  </div>
416
+ {% endif %}
417
+
418
+ {# Language selector #}
419
+ {% if _language_selector is not empty %}
420
+ {% include '@ecl/site-header/site-header-language-switcher.html.twig' with {
421
+ language_selector: _language_selector,
422
+ icon_path: _icon_path,
423
+ } only %}
424
+ {% endif %}
425
+
426
+ {# Search form #}
427
+ {% if _search_form is defined %}
428
+ <div class="ecl-site-header__search-container" role="search">
429
+ {% if _search_toggle is not empty %}
430
+ <a
431
+ class="ecl-button ecl-button--tertiary ecl-button--neutral ecl-site-header__search-toggle"
432
+ href="{{ _search_toggle.href }}"
433
+ data-ecl-search-toggle="true"
434
+ aria-controls="search-form-id"
435
+ aria-expanded="false"
436
+ >
437
+ {%- include '@ecl/icon/icon.html.twig' with {
438
+ icon: {
439
+ name: 'search',
440
+ path: _icon_path,
441
+ size: 'm',
442
+ },
443
+ as_image: true,
444
+ extra_classes: 'ecl-site-header__icon',
445
+ extra_accessibility: {
446
+ title: _search_toggle.label,
447
+ },
448
+ } only -%}
449
+ {{- _search_toggle.label -}}
450
+ </a>
451
+ {% endif %}
452
+ {% include '@ecl/search-form/search-form.html.twig' with _search_form only %}
453
+ </div>
454
+ {% endif %}
365
455
  </div>
366
456
  </div>
367
457
  </div>
@@ -382,26 +472,32 @@
382
472
 
383
473
  {# Banner top #}
384
474
  {% if banner_top is defined and banner_top is not empty %}
385
- <div class="ecl-site-header__banner-top">
386
- <div class="ecl-container">
387
- {%- if banner_top.link is defined and banner_top.link is not empty %}
388
- {% include '@ecl/link/link.html.twig' with banner_top|merge({
389
- link: banner_top.link|merge({ type: 'standalone', no_visited: true}),
390
- icon_path: _icon_path
391
- }) only %}
392
- {% else %}
393
- {{ banner_top }}
394
- {% endif -%}
475
+ <div class="ecl-container">
476
+ <div class="ecl-site-header__banner-top">
477
+ {%- if banner_top.link is defined and banner_top.link is not empty %}
478
+ {% include '@ecl/link/link.html.twig' with banner_top|merge({
479
+ link: banner_top.link|merge({ type: 'standalone', no_visited: true}),
480
+ }) only %}
481
+ {% else %}
482
+ {{ banner_top }}
483
+ {% endif -%}
395
484
  </div>
396
485
  </div>
397
486
  {% endif %}
398
487
 
399
488
  {# Site name and call to action (banner) #}
400
489
  {% if _site_name is not empty or _cta_link is not empty %}
401
- <div class="ecl-site-header__banner">
490
+ {% set _banner_class = 'ecl-site-header__banner' %}
491
+ {% if _site_name_mobile_only %}
492
+ {% set _banner_class = _banner_class ~ ' ecl-site-header__site-name--mobile-only' %}
493
+ {% endif %}
494
+ <div class="{{ _banner_class }}">
402
495
  <div class="ecl-container">
403
496
  {% if _site_name is not empty %}
404
- <div class="ecl-site-header__site-name">{{ _site_name }}</div>
497
+ {% set _site_name_class = 'ecl-site-header__site-name' %}
498
+ <div class="{{ _site_name_class }}">
499
+ {{- _site_name -}}
500
+ </div>
405
501
  {% endif %}
406
502
  {% if _cta_link is not empty and _cta_link.link is not empty %}
407
503
  {% include '@ecl/link/link.html.twig' with _cta_link|merge({
@@ -420,13 +516,11 @@
420
516
  {% if _menu is defined and _menu is not empty %}
421
517
  {% include '@ecl/menu/menu.html.twig' with _menu|merge({
422
518
  site_name: _site_name,
423
- icon_path: _icon_path,
424
519
  }) only %}
425
520
  {% endif %}
426
521
  {% if _mega_menu is defined and _mega_menu is not empty %}
427
522
  {% include '@ecl/mega-menu/mega-menu.html.twig' with _mega_menu|merge({
428
523
  site_name: _site_name,
429
- icon_path: _icon_path,
430
524
  }) only %}
431
525
  {% endif %}
432
526
  </header>