desy-html 8.7.0 → 8.8.0

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.
package/docs/index.html CHANGED
@@ -38,6 +38,13 @@
38
38
 
39
39
  <h2>Changelog (English)</h2>
40
40
  <p>What's new in the latest version of desy-html</p>
41
+ <h3>v.8.8.0</h3>
42
+ <ul class="text-sm">
43
+ <li>Added global function to select items in Listbox.</li>
44
+ <li>Added global function to open items in Accordion and Accordion history.</li>
45
+ <li>Fixed a bug in Tabs.</li>
46
+ <li>Improvements in Docs. Added menu navigation in header advanced in template example.</li>
47
+ </ul>
41
48
  <h3>v.8.7.0</h3>
42
49
  <ul class="text-sm">
43
50
  <li>Added global function to select items and subitems in Menubar and Menu horizontal.</li>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "desy-html",
3
- "version": "8.7.0",
3
+ "version": "8.8.0",
4
4
  "description": "desy-html contains the code you need to start building a user interface for Gobierno de Aragón government webapps.",
5
5
  "author": {
6
6
  "name": "Desy (SDA Servicios Digitales de Aragón)",
@@ -92,7 +92,6 @@ export function accordion(aria) {
92
92
  // If toggling is not allowed, set disabled state on trigger
93
93
  if (!allowToggle) {
94
94
  target.setAttribute('aria-disabled', 'true');
95
- //target.querySelector('span').innerText = '';
96
95
  target.querySelector('.c-accordion__show').classList.add('hidden');
97
96
  target.querySelector('.c-accordion__hide').classList.add('hidden');
98
97
  }
@@ -178,11 +177,56 @@ export function accordion(aria) {
178
177
  // If an expanded/ active accordion is found, disable
179
178
  if (expanded) {
180
179
  expanded.setAttribute('aria-disabled', 'true');
181
- //expanded.querySelector('span').innerText = '';
182
180
  expanded.querySelector('.c-accordion__show').classList.add('hidden');
183
181
  expanded.querySelector('.c-accordion__hide').classList.add('hidden');
184
182
  }
185
183
  }
186
184
 
185
+ window.activateItemAccordion = function (menuId, activeItemId) {
186
+ const menu = document.getElementById(menuId);
187
+ if (menu) {
188
+ const activeItem = document.querySelector(`#${menuId} #${activeItemId}`);
189
+ if (activeItem) {
190
+ activateElement(menuId, activeItemId);
191
+ return [menu, activeItem]
192
+ } else {
193
+ console.log('There is no element with this id in the menu.');
194
+ return null;
195
+ }
196
+ } else {
197
+ console.log('There is no menu with this id in the document.');
198
+ return null;
199
+ }
200
+ };
201
+
202
+ function activateElement(menu, activeItem) {
203
+ const getAccordion = document.querySelector(`#${menu}`);
204
+ const allowMultiple = getAccordion.hasAttribute('data-allow-multiple');
205
+ const allowToggle = (allowMultiple) ? allowMultiple : accordion.hasAttribute('data-allow-toggle');
206
+ const selectAllTriggers = document.querySelectorAll(`#${menu} .c-accordion__trigger`);
207
+ [...selectAllTriggers].forEach((trigger) => {
208
+ const getPanel = trigger.parentElement.parentElement.querySelector('.c-accordion__panel');
209
+ const getShowMessage = trigger.querySelector('.c-accordion__show');
210
+ const getHideMessage = trigger.querySelector('.c-accordion__hide');
211
+ if (isActive(trigger)) {
212
+ trigger.setAttribute('aria-expanded', 'true');
213
+ getPanel.removeAttribute('hidden');
214
+ getShowMessage.classList.add('hidden');
215
+ getHideMessage.classList.remove('hidden');
216
+ } else {
217
+ trigger.setAttribute('aria-expanded', 'false');
218
+ getPanel.setAttribute('hidden', 'true');
219
+ getShowMessage.classList.remove('hidden');
220
+ getHideMessage.classList.add('hidden');
221
+ }
222
+ });
223
+
224
+ function isActive(element){
225
+ const { id } = element;
226
+ return typeof activeItem === "object" && allowToggle
227
+ ? activeItem.includes(id)
228
+ : id === activeItem;
229
+ }
230
+ }
187
231
  });
188
232
  }
@@ -279,10 +279,6 @@ export function listbox(aria) {
279
279
  'aria-selected',
280
280
  element.getAttribute('aria-selected') === 'true' ? 'false' : 'true'
281
281
  );
282
- element.setAttribute(
283
- 'aria-checked',
284
- element.getAttribute('aria-checked') === 'true' ? 'false' : 'true'
285
- );
286
282
 
287
283
  if (this.moveButton) {
288
284
  if (this.listboxNode.querySelector('[aria-selected="true"]')) {
@@ -308,7 +304,6 @@ export function listbox(aria) {
308
304
  }
309
305
  if (!this.multiselectable) {
310
306
  element.removeAttribute('aria-selected');
311
- element.removeAttribute('aria-checked');
312
307
  }
313
308
  aria.Utils.removeClass(element, 'focused');
314
309
  };
@@ -324,7 +319,6 @@ export function listbox(aria) {
324
319
  this.defocusItem(document.getElementById(this.activeDescendant));
325
320
  if (!this.multiselectable) {
326
321
  element.setAttribute('aria-selected', 'true');
327
- element.setAttribute('aria-checked', 'true');
328
322
  }
329
323
  aria.Utils.addClass(element, 'focused');
330
324
  this.listboxNode.setAttribute('aria-activedescendant', element.id);
@@ -559,5 +553,72 @@ export function listbox(aria) {
559
553
  this.handleFocusChange = focusChangeHandler;
560
554
  };
561
555
 
556
+ function activateElement(menuId, activeItem) {
557
+ const getListBox = document.querySelector(`#${menuId}`);
558
+ const getTippy = document.querySelector(`#${menuId} [data-tippy-root]`);
559
+ const getTippyBox = document.querySelector(`#${menuId} .tippy-box`);
560
+ const getListBoxUl = document.querySelector(`#${menuId} [data-module="c-listbox-list"]`);
561
+ const getListBoxButton = document.querySelector(`#${menuId} .c-listbox`);
562
+ const getListBoxButtonText = document.querySelector(`#${menuId} .c-listbox span`);
563
+ const getMultiSelectable = getListBoxButton.getAttribute('aria-labelledby');
564
+ const allowMultiple = getMultiSelectable.includes('is-multiselectable-label');
565
+ const selectAllElements = document.querySelectorAll(`#${menuId} li`);
566
+
567
+ getListBoxButton.click();
568
+ getTippy.style.visibility = 'visible';
569
+ getTippyBox.setAttribute('data-state','visible');
570
+ getListBoxButton._tippy.popper._tippy.show();
571
+ getListBoxUl.focus();
572
+
573
+ [...selectAllElements].forEach((element) => {
574
+ if (isActive(element, activeItem)) {
575
+ element.setAttribute('aria-selected', 'true');
576
+ if(!allowMultiple && getListBoxButton.dataset.change){
577
+ getListBoxButtonText.innerHTML = element.textContent;
578
+ }
579
+ } else {
580
+ element.setAttribute('aria-selected', 'false');
581
+ }
582
+ });
583
+
584
+ getTippy.style.visibility = 'hidden';
585
+ getTippyBox.setAttribute('data-state','hidden');
586
+
587
+ getListBoxUl.dispatchEvent(new KeyboardEvent("keydown", {
588
+ key: "Escape",
589
+ keyCode: 27,
590
+ code: "Escape",
591
+ which: 27
592
+ }));
593
+
594
+ getListBoxButton._tippy.popper._tippy.hide();
595
+ getListBoxButton.classList.remove('open');
596
+
597
+ function isActive(element, activeItem) {
598
+ const { id } = element;
599
+ return typeof activeItem === "object" && allowMultiple
600
+ ? activeItem.includes(id)
601
+ : id === activeItem;
602
+ }
603
+ };
604
+
605
+ window.activateItemListBox = function (menuId, activeItemId) {
606
+ const menu = document.getElementById(menuId);
607
+ if (menu) {
608
+ const getListBoxButton = document.querySelector(`#${menuId} .c-listbox`);
609
+ getListBoxButton.click();
610
+ const activeItem = document.querySelector(`#${menuId} #${activeItemId}`);
611
+ if (activeItem) {
612
+ activateElement(menuId, activeItemId);
613
+ return [menu, activeItem]
614
+ } else {
615
+ console.log('There is no element with this id in the menu.');
616
+ return null;
617
+ }
618
+ } else {
619
+ console.log('There is no menu with this id in the document.');
620
+ return null;
621
+ }
622
+ };
562
623
  return aria;
563
- }
624
+ }
@@ -281,13 +281,18 @@ export function tabs(aria) {
281
281
  //Add active class to current tab
282
282
  element.classList.add("c-tabs__link--is-active");
283
283
  element.setAttribute('role', 'tab');
284
- element.innerHTML = `<strong class="font-bold">${element.innerHTML}</strong>`;
284
+ if(element.querySelector('strong') === null) {
285
+ element.innerHTML = `<strong class="font-bold">${element.innerHTML}</strong>` ;
286
+ }
285
287
  }
286
288
 
287
289
  function removeActiveClass(element) {
288
290
  element.classList.remove("c-tabs__link--is-active");
289
291
  element.removeAttribute('role');
290
- element.innerHTML = element.innerHTML;
292
+ if(element.querySelector('strong')) {
293
+ const replaceStrong = element.innerHTML.replace('<strong class="font-bold">', '').replace('<strong/>', '');
294
+ element.innerHTML = `${replaceStrong}`;
295
+ }
291
296
  }
292
297
 
293
298
  window.activateItemTabs = function (menuId, tabItemId) {
@@ -296,16 +301,13 @@ export function tabs(aria) {
296
301
  const activeItemTab = document.querySelector(`#${menuId} #${tabItemId}`);
297
302
  const activeItemPanel = document.querySelector(`[aria-labelledby="${tabItemId}"]`);
298
303
  if (activeItemTab) {
299
- document.querySelectorAll('.c-tabs__link').forEach((tab) => {
300
- tab.classList.remove("c-tabs__link--is-active");
301
- tab.innerHTML = tab.innerHTML;
304
+ document.querySelectorAll(`#${menuId} .c-tabs__link`).forEach((tab) => {
305
+ removeActiveClass(tab)
302
306
  })
303
307
 
304
- activeItemTab.classList.add("c-tabs__link--is-active");
305
- activeItemTab.setAttribute('role', 'tab');
306
- activeItemTab.innerHTML = `<strong class="font-bold">${activeItemTab.innerHTML}</strong>`;
308
+ addActiveClass(activeItemTab)
307
309
 
308
- document.querySelectorAll('.c-tabs__panel').forEach((panel) => {
310
+ document.querySelectorAll(`#${menuId} .c-tabs__panel`).forEach((panel) => {
309
311
  panel.setAttribute('hidden', 'hidden')
310
312
  })
311
313
 
@@ -126,17 +126,36 @@ export function dropdownComponent(aria) {
126
126
  export function listboxComponent(aria) {
127
127
  listbox(aria);
128
128
  const modules = document.querySelectorAll('[data-module]');
129
+ let activeButton;
129
130
  for (const item in modules) if (modules.hasOwnProperty(item)) {
130
131
  const moduleValue = modules[item].getAttribute('data-module');
131
132
 
132
-
133
133
  if (moduleValue == 'c-listbox'){
134
134
  const buttonListbox = modules[item].querySelector('[data-module = "c-listbox-button"]');
135
135
  const tooltip = modules[item].querySelector('[data-module = "c-listbox-tooltip"]');
136
136
  const list = modules[item].querySelector('[data-module = "c-listbox-list"]');
137
-
138
137
  if(buttonListbox && tooltip) {
139
138
  const listbox = new aria.Listbox(list);
139
+ const hideOnClick = {
140
+ name: 'hideOnClick',
141
+ defaultValue: true,
142
+ fn(instance) {
143
+ return {
144
+ onCreate() {
145
+ buttonListbox.addEventListener("click", (event) => {
146
+ if(!buttonListbox.classList.contains('open')){
147
+ instance.show();
148
+ list.focus()
149
+ buttonListbox.classList.add('open');
150
+ } else {
151
+ list.blur();
152
+ instance.hide();
153
+ }
154
+ });
155
+ },
156
+ };
157
+ },
158
+ };
140
159
  const hideOnPopperBlur = {
141
160
  /* https://atomiks.github.io/tippyjs/v6/plugins/#hideonpopperblur */
142
161
  name: 'hideOnPopperBlur',
@@ -185,34 +204,40 @@ export function listboxComponent(aria) {
185
204
  inlinePositioning: true,
186
205
  content: tooltip,
187
206
  allowHTML: true, // Make sure you are sanitizing any user data if rendering HTML to prevent XSS attacks.
188
- trigger: 'click',
189
- hideOnClick: true,
207
+ trigger: 'manual',
190
208
  interactive: true,
191
209
  arrow: false,
192
210
  offset: [0, -10],
193
211
  theme: '',
194
- plugins: [hideOnEscOrEnter,hideOnPopperBlur],
212
+ plugins: [hideOnEscOrEnter,hideOnPopperBlur, hideOnClick],
195
213
  role: false,
196
214
  aria: {
197
215
  content: 'auto'
198
216
  },
199
- onShown(instance) {
200
- list.focus();
217
+ onMount(instance) {
201
218
  if (list.querySelectorAll('[aria-selected="true"]')[0]) {
202
219
  listbox.focusItem(list.querySelectorAll('[aria-selected="true"]')[0]);
203
220
  }
204
221
  },
205
- onHidden(instance) {
206
- buttonListbox.focus();
222
+ onHidden(instance){
223
+ buttonListbox.classList.remove('open');
207
224
  }
208
225
  });
209
226
 
210
227
  listbox.setHandleFocusChange(function(evt){
211
- if ((!list.hasAttribute('aria-multiselectable'))&&(buttonListbox.getAttribute('data-change')=='change')){
228
+ if ((!list.hasAttribute('aria-multiselectable')) && (buttonListbox.getAttribute('data-change')=='change')){
212
229
  buttonListbox.firstElementChild.innerHTML = evt.innerHTML;
213
230
  }
214
231
  });
215
232
 
233
+ const getMultiSelectable = buttonListbox.getAttribute('aria-labelledby');
234
+ const allowMultiple = getMultiSelectable.includes('is-multiselectable-label');
235
+
236
+ if(!allowMultiple) {
237
+ list.addEventListener("click", (event) => {
238
+ buttonListbox.click();
239
+ })
240
+ }
216
241
  }
217
242
  }
218
243
  }
@@ -70,7 +70,7 @@
70
70
  },
71
71
  {
72
72
  "name": "Con un item abierto",
73
- "description": 'Podemos abrir inicialmente un item si le añadimos el parámetro <code>"open": true</code>.',
73
+ "description": 'Podemos abrir inicialmente un item si le añadimos el parámetro <code>"open": true</code>. También puedes usar con javascript la función global <code>activateItemAccordion(elementMenu, activeItemId)</code> para abrir un item, usando sus ids. Ej: Abre la consola del navegador y escribe <code>activateItemAccordion("accordion", "with-one-item-opened-example-1-title")</code> para cerrar el item actual y abrir el primer item de este ejemplo.',
74
74
  "data": {
75
75
  "idPrefix": "with-one-item-opened-example",
76
76
  "headingLevel": 3,
@@ -89,12 +89,15 @@
89
89
  "headerText": "Item de acordeón 3",
90
90
  "html": '<div class="w-48 p-2"><div class="border-4 border-dashed border-neutral-light rounded-lg h-40"></div></div>'
91
91
  }
92
- ]
92
+ ],
93
+ "attributes": {
94
+ "id": "accordion"
95
+ }
93
96
  }
94
97
  },
95
98
  {
96
99
  "name": "Con 2 items abiertos",
97
- "description": 'Podemos abrir inicialmente items si les añadimos el parámetro <code>"open": true</code>.',
100
+ "description": 'Podemos abrir inicialmente items si les añadimos el parámetro <code>"open": true</code>. También puedes usar con javascript la función global <code>activateItemAccordion(elementMenu, activeItemsIds)</code> para abrir varios items, usando sus ids. Ej: Abre la consola del navegador y escribe <code>activateItemAccordion("accordion-multiple", ["with-2-items-opened-example-2-title", "with-2-items-opened-example-3-title"])</code>.',
98
101
  "data": {
99
102
  "idPrefix": "with-2-items-opened-example",
100
103
  "headingLevel": 3,
@@ -114,7 +117,10 @@
114
117
  "html": '<div class="w-48 p-2"><div class="border-4 border-dashed border-neutral-light rounded-lg h-40"></div></div>',
115
118
  "open": true
116
119
  }
117
- ]
120
+ ],
121
+ "attributes": {
122
+ "id": "accordion-multiple"
123
+ }
118
124
  }
119
125
  },
120
126
  {
@@ -106,7 +106,7 @@
106
106
  },
107
107
  {
108
108
  "name": "Con un item abierto",
109
- "description": 'Podemos abrir inicialmente un item si le añadimos el parámetro <code>"open": true</code>.',
109
+ "description": 'Podemos abrir inicialmente un item si le añadimos el parámetro <code>"open": true</code>. También puedes usar con javascript la función global <code>activateItemAccordion(elementMenu, activeItemId)</code> para abrir un item, usando sus ids. Ej: Abre la consola del navegador y escribe <code>activateItemAccordion("accordion-history", "with-one-item-opened-example-1-title")</code> para cerrar el item actual y abrir el primer item de este ejemplo.',
110
110
  "data": {
111
111
  "idPrefix": "with-one-item-opened-example",
112
112
  "headingLevel": 3,
@@ -125,12 +125,15 @@
125
125
  "headerText": "Item de acordeón 3",
126
126
  "html": '<div class="w-48 p-2"><div class="border-4 border-dashed border-neutral-light rounded-lg h-40"></div></div>'
127
127
  }
128
- ]
128
+ ],
129
+ "attributes": {
130
+ "id": "accordion-history"
131
+ }
129
132
  }
130
133
  },
131
134
  {
132
135
  "name": "Con 2 items abiertos",
133
- "description": 'Podemos abrir inicialmente items si les añadimos el parámetro <code>"open": true</code>.',
136
+ "description": 'Podemos abrir inicialmente items si les añadimos el parámetro <code>"open": true</code>. También puedes usar con javascript la función global <code>activateItemAccordion(elementMenu, activeItemsIds)</code> para abrir varios items, usando sus ids. Ej: Abre la consola del navegador y escribe <code>activateItemAccordion("accordion-history-multiple", ["with-2-items-opened-example-2-title", "with-2-items-opened-example-3-title"])</code>.',
134
137
  "data": {
135
138
  "idPrefix": "with-2-items-opened-example",
136
139
  "headingLevel": 3,
@@ -150,7 +153,10 @@
150
153
  "html": '<div class="w-48 p-2"><div class="border-4 border-dashed border-neutral-light rounded-lg h-40"></div></div>',
151
154
  "open": true
152
155
  }
153
- ]
156
+ ],
157
+ "attributes": {
158
+ "id": "accordion-history-multiple"
159
+ }
154
160
  }
155
161
  },
156
162
  {
@@ -380,4 +386,4 @@
380
386
  ]
381
387
  }
382
388
  }
383
- ] %}
389
+ ] %}
@@ -444,6 +444,7 @@
444
444
  },
445
445
  {
446
446
  "name": "con item activo",
447
+ "description": 'Podemos seleccionar inicialmente un item si le añadimos el parámetro <code>"active": true</code>. También puedes usar con javascript la función global <code>activateItemListBox(elementMenu, activeItemId)</code> para seleccionar un item, usando sus ids. Ej: Abre la consola del navegador y escribe <code>activateItemListBox("listbox", "with-active-item-listbox-item-2")</code> para seleccionar el segundo item de este ejemplo.',
447
448
  "data": {
448
449
  "id": "with-active-item",
449
450
  "text": "con item activo",
@@ -472,12 +473,15 @@
472
473
  "href": "#",
473
474
  "text": "Opción 5"
474
475
  }
475
- ]
476
+ ],
477
+ "attributes": {
478
+ "id": "listbox"
479
+ }
476
480
  }
477
481
  },
478
482
  {
479
483
  "name": "Permite selecciones múltiples",
480
- "description": 'Usa el parámetro <code>"isMultiselectable": true</code>.',
484
+ "description": 'Usa el parámetro <code>"isMultiselectable": true</code>. En este caso al seleccionar un item el elemento no se cerrará. También puedes usar con javascript la función global <code>activateItemListBox(elementMenu, activeItemId)</code> para seleccionar varios items, usando sus ids. Ej: Abre la consola del navegador y escribe <code>activateItemListBox("listbox-multiple", ["is-multiselectable-listbox-item-2", "is-multiselectable-listbox-item-3"])</code> para seleccionar el segundo y el tercer item de este ejemplo.',
481
485
  "data": {
482
486
  "id": "is-multiselectable",
483
487
  "isMultiselectable": true,
@@ -506,7 +510,10 @@
506
510
  "href": "#",
507
511
  "text": "Opción 5"
508
512
  }
509
- ]
513
+ ],
514
+ "attributes": {
515
+ "id": "listbox-multiple"
516
+ }
510
517
  }
511
518
  },
512
519
  {
@@ -609,4 +616,4 @@
609
616
  ]
610
617
  }
611
618
  }
612
- ] %}
619
+ ] %}
@@ -66,7 +66,7 @@ treat it as an interactive element - without this it will be
66
66
  {% endset -%}
67
67
 
68
68
  <!-- listbox -->
69
- <div data-module="c-listbox" class="{% if params.classesContainer %}{{ params.classesContainer }}{% else %} relative{% endif %}">
69
+ <div data-module="c-listbox" class="{% if params.classesContainer %}{{ params.classesContainer }}{% else %} relative{% endif %}" {%- for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %}>
70
70
  {% if params.label %}
71
71
  <div id="{{ params.id }}-label" class="mb-sm {%- if params.label.classes %} {{ params.label.classes }}{% endif %}">
72
72
  {% if params.label.html %}
@@ -87,4 +87,4 @@ treat it as an interactive element - without this it will be
87
87
  </ul>
88
88
  </div>
89
89
  </div>
90
- <!-- /listbox -->
90
+ <!-- /listbox -->
@@ -366,7 +366,10 @@
366
366
  "html": "<p><strong>Panel 3</strong>. Provident animi dolor veniam, et quas consequuntur. Reiciendis eius in, nostrum porro? Quaerat, temporibus, optio? Lorem ipsum dolor sit, amet, consectetur adipisicing elit. Est quis exercitationem, nesciunt nulla quisquam temporibus. Provident animi dolor veniam, et quas consequuntur.</p>"
367
367
  }
368
368
  }
369
- ]
369
+ ],
370
+ "attributes": {
371
+ "id": "tabs-active-icons"
372
+ }
370
373
  }
371
374
  },
372
375
  {
@@ -1,6 +1,8 @@
1
1
  {% include "pages/_page.head.njk" %}
2
2
 
3
3
  {% from "components/header-advanced/_macro.header-advanced.njk" import componentHeaderAdvanced %}
4
+ {% from "components/menu-vertical/_macro.menu-vertical.njk" import componentMenuVertical %}
5
+ {% from "components/menu-navigation/_macro.menu-navigation.njk" import componentMenuNavigation %}
4
6
  {% from "components/nav/_macro.nav.njk" import componentNav %}
5
7
  {% from "components/details/_macro.details.njk" import componentDetails %}
6
8
 
@@ -13,6 +15,132 @@
13
15
  <!-- /pageSpinnerBlock -->
14
16
  <!-- headerBlock -->
15
17
  {% block headerBlock %}
18
+ {% set menuCustom %}
19
+ <div class="hidden lg:flex lg:flex-wrap lg:flex-1 lg:gap-base">
20
+ {{ componentMenuNavigation({
21
+ "idPrefix": "header-custom-nav",
22
+ "classes": "bg-neutral-lighter c-menu-navigation--last-right w-full",
23
+ "items": [
24
+ {
25
+ "text": "Inicio",
26
+ "active": true,
27
+ "id": "header-custom-nav-item-0",
28
+ "classes": "c-menu-navigation__button--header -mr-base",
29
+ "href": "#"
30
+ },
31
+ {
32
+ "text": "Gestiones",
33
+ "id": "header-custom-nav-item-1",
34
+ "classes": "c-menu-navigation__button--header -mr-base",
35
+ "sub": {
36
+ "items": [
37
+ {
38
+ "href": "#",
39
+ "text": "Subitem 1"
40
+ },
41
+ {
42
+ "href": "#",
43
+ "text": "Subitem 2"
44
+ },
45
+ {
46
+ "href": "#",
47
+ "text": "Subitem 3"
48
+ }
49
+ ],
50
+ "attributes": {
51
+ "aria-labelledby": "header-custom-nav-item-1"
52
+ }
53
+ }
54
+ },
55
+ {
56
+ "text": "Centros sanitarios",
57
+ "id": "header-custom-nav-item-2",
58
+ "classes": "c-menu-navigation__button--header -mr-base",
59
+ "sub": {
60
+ "items": [
61
+ {
62
+ "href": "#",
63
+ "text": "Subitem 1"
64
+ },
65
+ {
66
+ "href": "#",
67
+ "text": "Subitem 2",
68
+ "active": true
69
+ },
70
+ {
71
+ "href": "#",
72
+ "text": "Subitem 3"
73
+ }
74
+ ],
75
+ "attributes": {
76
+ "aria-labelledby": "header-custom-nav-item-2"
77
+ }
78
+ }
79
+ },
80
+ {
81
+ "text": "Cuida tu salud",
82
+ "id": "header-custom-nav-item-3",
83
+ "classes": "c-menu-navigation__button--header -mr-base",
84
+ "sub": {
85
+ "items": [
86
+ {
87
+ "href": "#",
88
+ "text": "Subitem 1"
89
+ },
90
+ {
91
+ "href": "#",
92
+ "text": "Subitem 2"
93
+ },
94
+ {
95
+ "href": "#",
96
+ "text": "Subitem 3"
97
+ }
98
+ ],
99
+ "attributes": {
100
+ "aria-labelledby": "header-custom-nav-item-3"
101
+ }
102
+ }
103
+ },
104
+ {
105
+ "text": "Participación",
106
+ "id": "header-custom-nav-item-4",
107
+ "classes": "c-menu-navigation__button--header -mr-base",
108
+ "href": "#"
109
+ },
110
+ {
111
+ "text": "Contacto",
112
+ "id": "header-custom-nav-item-5",
113
+ "classes": "c-menu-navigation__button--header -mr-base",
114
+ "href": "#"
115
+ },
116
+ {
117
+ "text": "Hola, Marta",
118
+ "id": "header-custom-nav-item-6",
119
+ "classes": "c-menu-navigation__button--header",
120
+ "sub": {
121
+ "items": [
122
+ {
123
+ "href": "#",
124
+ "text": "Perfil"
125
+ },
126
+ {
127
+ "href": "#",
128
+ "text": "Cerrar sesión"
129
+ }
130
+ ],
131
+ "attributes": {
132
+ "aria-labelledby": "header-custom-nav-item-6"
133
+ }
134
+ }
135
+ }
136
+ ],
137
+ "attributes": {
138
+ "aria-label": "Menu de navegación principal",
139
+ "id": "mi-menu-header"
140
+ }
141
+ }) }}
142
+ </div>
143
+ {% endset %}
16
144
  {% call componentHeaderAdvanced({
17
145
  "skipLink": {
18
146
  "href": "#content"
@@ -21,35 +149,7 @@
21
149
  "homepageUrl": "index.html",
22
150
  "text": "Portal de Salud"
23
151
  },
24
- "navigation": {
25
- "items": [
26
- {
27
- "href": "#",
28
- "text": "Inicio",
29
- "active": true
30
- },
31
- {
32
- "href": "#",
33
- "text": "Gestiones"
34
- },
35
- {
36
- "href": "#",
37
- "text": "Centros sanitarios"
38
- },
39
- {
40
- "href": "#",
41
- "text": "Cuida tu salud"
42
- },
43
- {
44
- "href": "#",
45
- "text": "Participación"
46
- },
47
- {
48
- "href": "#",
49
- "text": "Contacto"
50
- }
51
- ]
52
- },
152
+ "customNavigationHtml": menuCustom | safe,
53
153
  "offcanvas": {
54
154
  "text": "Menú",
55
155
  "textClose": "Cerrar menú"
@@ -59,39 +159,120 @@
59
159
  <nav class="w-full p-2" aria-labelledby="menu-movil-title">
60
160
  <h2 id="menu-movil-title" class="sr-only">Menú principal</h2>
61
161
  <h3 class="p-base text-base font-bold">Portal de Salud</h3>
62
- {{ componentNav({
63
- "idPrefix": "nav-mobile-pages",
64
- "hasNav": false,
162
+ {{ componentMenuVertical({
163
+ "idPrefix": "menu-mobile",
65
164
  "items": [
66
165
  {
67
166
  "href": "#",
68
167
  "text": "Inicio",
168
+ "id": "menu-mobile-item-0",
69
169
  "active": true
70
170
  },
71
171
  {
72
172
  "href": "#",
73
- "text": "Gestiones"
173
+ "text": "Gestiones",
174
+ "id": "menu-mobile-item-1",
175
+ "sub": {
176
+ "items": [
177
+ {
178
+ "href": "#",
179
+ "text": "Subitem 1"
180
+ },
181
+ {
182
+ "href": "#",
183
+ "text": "Subitem 2"
184
+ },
185
+ {
186
+ "href": "#",
187
+ "text": "Subitem 3"
188
+ }
189
+ ],
190
+ "attributes": {
191
+ "aria-labelledby": "menu-mobile-item-1"
192
+ }
193
+ }
74
194
  },
75
195
  {
76
196
  "href": "#",
77
- "text": "Centros sanitarios"
197
+ "text": "Centros sanitarios",
198
+ "id": "menu-mobile-item-2",
199
+ "sub": {
200
+ "items": [
201
+ {
202
+ "href": "#",
203
+ "text": "Subitem 1"
204
+ },
205
+ {
206
+ "href": "#",
207
+ "text": "Subitem 2"
208
+ },
209
+ {
210
+ "href": "#",
211
+ "text": "Subitem 3"
212
+ }
213
+ ],
214
+ "attributes": {
215
+ "aria-labelledby": "menu-mobile-item-2"
216
+ }
217
+ }
78
218
  },
79
219
  {
80
220
  "href": "#",
81
- "text": "Cuida tu salud"
221
+ "text": "Cuida tu salud",
222
+ "id": "menu-mobile-item-3",
223
+ "sub": {
224
+ "items": [
225
+ {
226
+ "href": "#",
227
+ "text": "Subitem 1"
228
+ },
229
+ {
230
+ "href": "#",
231
+ "text": "Subitem 2"
232
+ },
233
+ {
234
+ "href": "#",
235
+ "text": "Subitem 3"
236
+ }
237
+ ],
238
+ "attributes": {
239
+ "aria-labelledby": "menu-mobile-item-3"
240
+ }
241
+ }
82
242
  },
83
243
  {
84
244
  "href": "#",
85
- "text": "Participación"
245
+ "text": "Participación",
246
+ "id": "menu-mobile-item-4"
86
247
  },
87
248
  {
88
249
  "href": "#",
89
- "text": "Contacto"
250
+ "text": "Contacto",
251
+ "id": "menu-mobile-item-5"
90
252
  }
91
253
  ],
92
254
  "attributes": {
93
255
  "aria-label": "Lista de páginas"
94
256
  }
257
+ }) }}
258
+ <hr class="mt-lg mb-base border-b border-neutral-base">
259
+ <h3 class="p-base text-base font-bold">Usuario/a: Ana Pérez</h3>
260
+ {{ componentNav({
261
+ "idPrefix": "nav-mobile-user",
262
+ "hasNav": false,
263
+ "items": [
264
+ {
265
+ "href": "#",
266
+ "text": "Perfil"
267
+ },
268
+ {
269
+ "href": "#",
270
+ "text": "Cerrar sesión"
271
+ }
272
+ ],
273
+ "attributes": {
274
+ "aria-label": "Lista de acciones de usuario"
275
+ }
95
276
  }) }}
96
277
  </nav>
97
278
  {% endcall %}