desy-html 8.9.0 → 8.10.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.
Files changed (31) hide show
  1. package/docs/ds/_ds.section.espaciado.njk +0 -58
  2. package/docs/index.html +9 -0
  3. package/package.json +2 -2
  4. package/src/css/component.text.css +8 -0
  5. package/src/css/styles.css +1 -0
  6. package/src/js/aria/HeaderNavigation.js +1 -1
  7. package/src/js/aria/MenuNavigation.js +6 -6
  8. package/src/js/aria/checkBoxes.js +18 -12
  9. package/src/js/aria/collapsible.js +36 -34
  10. package/src/js/aria/dialog.js +1 -0
  11. package/src/js/aria/listbox.js +23 -1
  12. package/src/js/aria/radioButton.js +18 -2
  13. package/src/js/desy-html.js +5 -0
  14. package/src/templates/components/breadcrumbs/_examples.breadcrumbs.njk +125 -8
  15. package/src/templates/components/breadcrumbs/_styles.breadcrumbs.css +9 -1
  16. package/src/templates/components/breadcrumbs/_template.breadcrumbs.njk +5 -1
  17. package/src/templates/components/breadcrumbs/params.breadcrumbs.yaml +4 -0
  18. package/src/templates/components/card/_examples.card.njk +16 -0
  19. package/src/templates/components/checkboxes/_examples.checkboxes.njk +62 -0
  20. package/src/templates/components/collapsible/_examples.collapsible.njk +19 -4
  21. package/src/templates/components/collapsible/_styles.collapsible.css +33 -0
  22. package/src/templates/components/collapsible/_template.collapsible.njk +5 -5
  23. package/src/templates/components/dialog/_examples.dialog.njk +47 -3
  24. package/src/templates/components/header/_template.header.header__offcanvas.njk +1 -1
  25. package/src/templates/components/header/_template.header.njk +1 -2
  26. package/src/templates/components/header-advanced/params.header-advanced.yaml +3 -3
  27. package/src/templates/components/header-mini/_examples.header-mini.njk +1 -1
  28. package/src/templates/components/header-mini/params.header-mini.yaml +2 -2
  29. package/src/templates/components/listbox/_examples.listbox.njk +37 -0
  30. package/src/templates/components/menu-navigation/_template.menu-navigation.njk +1 -1
  31. package/src/templates/components/radios/_examples.radios.njk +72 -2
@@ -136,64 +136,6 @@
136
136
  <p>
137
137
  Utiliza en la medida de lo posible estos valores para establecer valores de width y max-width.
138
138
  </p>
139
- <table>
140
- <thead>
141
- <tr>
142
- <th>Nombre</th>
143
- <th>Tamaño</th>
144
- <th>Pixels</th>
145
- <th>Ejemplo de clases</th>
146
- <th class="hidden sm:table-cell"><span class="sr-only">Previsualización</span></th>
147
- </tr>
148
- </thead>
149
- <tbody>
150
- <tr>
151
- <td>xs</td>
152
- <td>20rem</td>
153
- <td>320px</td>
154
- <td><code>w-xs</code></td>
155
- <td class="hidden sm:table-cell">
156
- <div class="inline-block w-xs h-4 bg-primary-base text-transparent overflow-hidden"><span class="sr-only">||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||</span></div>
157
- </td>
158
- </tr>
159
- <tr>
160
- <td>sm</td>
161
- <td>24rem</td>
162
- <td>384px</td>
163
- <td><code>w-sm</code></td>
164
- <td class="hidden sm:table-cell">
165
- <div class="inline-block w-sm h-4 bg-primary-base text-transparent overflow-hidden"><span class="sr-only">||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||</span></div>
166
- </td>
167
- </tr>
168
- <tr>
169
- <td>md</td>
170
- <td>28rem</td>
171
- <td>448px</td>
172
- <td><code>w-md</code></td>
173
- <td class="hidden sm:table-cell">
174
- <div class="inline-block w-md h-4 bg-primary-base text-transparent overflow-hidden"><span class="sr-only">||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||</span></div>
175
- </td>
176
- </tr>
177
- <tr>
178
- <td>lg</td>
179
- <td>32rem</td>
180
- <td>512px</td>
181
- <td><code>w-lg</code></td>
182
- <td class="hidden sm:table-cell">
183
- <div class="inline-block w-lg h-4 bg-primary-base text-transparent overflow-hidden"><span class="sr-only">||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||</span></div>
184
- </td>
185
- </tr>
186
- <tr>
187
- <td>xl</td>
188
- <td>36rem</td>
189
- <td>576px</td>
190
- <td><code>w-xl</code></td>
191
- <td class="hidden sm:table-cell">
192
- <div class="inline-block w-xl h-4 bg-primary-base text-transparent overflow-hidden"><span class="sr-only">||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||</span></div>
193
- </td>
194
- </tr>
195
- </tbody>
196
- </table>
197
139
  <div class="max-w-full overflow-x-auto">
198
140
  <table>
199
141
  <thead>
package/docs/index.html CHANGED
@@ -38,6 +38,15 @@
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.10.0</h3>
42
+ <ul class="text-sm">
43
+ <li>Updated to Tailwind CSS v3.3.5</li>
44
+ <li>Fixed bugs in Checkboxes and Radio conditionals.</li>
45
+ <li>Added global function to select items in Listbox.</li>
46
+ <li>Added global function to open/close Collapsible and Dialog.</li>
47
+ <li>Accesibility improvements.</li>
48
+ <li>Improvements in Docs.</li>
49
+ </ul>
41
50
  <h3>v.8.9.0</h3>
42
51
  <ul class="text-sm">
43
52
  <li>Added global function to select items and refactor Menu navigation to fix keyboard navigation.</li>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "desy-html",
3
- "version": "8.9.0",
3
+ "version": "8.10.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)",
@@ -41,7 +41,7 @@
41
41
  "postcss": "^8.2.15",
42
42
  "postcss-cli": "^10.0.0",
43
43
  "postcss-import": "^15.0.0",
44
- "tailwindcss": "~3.2.1"
44
+ "tailwindcss": "^3.3.5"
45
45
  },
46
46
  "devDependencies": {
47
47
  "browser-sync": "^2.26.13",
@@ -73,6 +73,14 @@
73
73
  }
74
74
  }
75
75
 
76
+ .c-link--full {
77
+ &::after {
78
+ content:"";
79
+ @apply absolute;
80
+ @apply inset-0;
81
+ }
82
+ }
83
+
76
84
  .c-paragraph-lg {
77
85
  @apply mb-lg;
78
86
  @apply text-lg;
@@ -20,6 +20,7 @@
20
20
  @import "../templates/components/button/_styles.button.css";
21
21
  @import "../templates/components/button-loader/_styles.button-loader.css";
22
22
  @import "../templates/components/checkboxes/_styles.checkboxes.css";
23
+ @import "../templates/components/collapsible/_styles.collapsible.css";
23
24
  @import "../templates/components/dialog/_styles.dialog.css";
24
25
  @import "../templates/components/dropdown/_styles.dropdown.css";
25
26
  @import "../templates/components/header/_styles.header.css";
@@ -25,7 +25,7 @@ export function HeaderNavigation(aria) {
25
25
  };
26
26
 
27
27
  aria.HeaderNavigation.prototype.wrapActiveElement = function (elementActive) {
28
- elementActive.setAttribute('aria-current', 'true');
28
+ elementActive.setAttribute('aria-current', 'page');
29
29
  elementActive.innerHTML = `<strong class="font-bold">${elementActive.textContent}</strong>`;
30
30
  };
31
31
 
@@ -31,7 +31,7 @@ export function MenuNavigation(aria) {
31
31
  if(this.rootNode.querySelectorAll('.c-menu-navigation__sub--list')) {
32
32
  const subItems = this.rootNode.querySelectorAll('.c-menu-navigation__sub--list li a');
33
33
  [...subItems].forEach((element) => {
34
- if(element.getAttribute("aria-current") === "true"){
34
+ if(element.getAttribute("aria-current") === "page"){
35
35
  const getElement = element.parentElement.parentElement.parentElement.parentElement.querySelector('button');
36
36
  getElement.classList.add('c-menu-navigation__button--primary', 'c-menu-navigation__button--has-selection');
37
37
  getElement.firstChild.innerHTML = `<strong class="font-bold">${getElement.textContent}</strong>`;
@@ -90,18 +90,18 @@ export function MenuNavigation(aria) {
90
90
  const getAllLinks = this.rootNode.querySelectorAll(`#${menuId} ul li li a`);
91
91
  [...getAllLinks].forEach((link) => {
92
92
  if(link.id === elementActive) {
93
- link.setAttribute('aria-current', 'true');
93
+ link.setAttribute('aria-current', 'page');
94
94
  link.innerHTML = `<strong class="font-bold">${link.textContent}</strong>`;
95
95
  } else {
96
96
  const getElementParent = link.parentElement.parentElement.parentElement.parentElement.querySelector('button');
97
97
  getElementParent.classList.remove('c-menu-navigation__button--primary', 'c-menu-navigation__button--has-selection');
98
98
  getElementParent.firstChild.innerHTML = `${getElementParent.textContent}`;
99
- link.setAttribute('aria-current', 'false');
99
+ link.removeAttribute('aria-current');
100
100
  link.innerHTML = `${link.textContent}`;
101
101
  }
102
102
  });
103
103
  [...getAllLinks].forEach((link) => {
104
- if(link.getAttribute("aria-current") === "true"){
104
+ if(link.getAttribute("aria-current") === "page"){
105
105
  const getElementParent = link.parentElement.parentElement.parentElement.parentElement.querySelector('button');
106
106
  getElementParent.classList.add('c-menu-navigation__button--primary', 'c-menu-navigation__button--has-selection');
107
107
  getElementParent.firstChild.innerHTML = `<strong class="font-bold">${getElementParent.textContent}</strong>`;
@@ -110,13 +110,13 @@ export function MenuNavigation(aria) {
110
110
  };
111
111
 
112
112
  aria.MenuNavigation.prototype.wrapActiveElement = function (elementActive) {
113
- elementActive.setAttribute('aria-current', 'true');
113
+ elementActive.setAttribute('aria-current', 'page');
114
114
  elementActive.classList.add('c-menu-navigation__button--primary', 'c-menu-navigation__button--has-selection');
115
115
  elementActive.innerHTML = `<strong class="font-bold">${elementActive.textContent}</strong>`;
116
116
  };
117
117
 
118
118
  aria.MenuNavigation.prototype.deactivateElement = function (elementDeactivated) {
119
- elementDeactivated.setAttribute('aria-current', 'false');
119
+ elementDeactivated.removeAttribute('aria-current');
120
120
  elementDeactivated.classList.remove('c-menu-navigation__button--primary', 'c-menu-navigation__button--has-selection');
121
121
  elementDeactivated.innerHTML = elementDeactivated.textContent;
122
122
  };
@@ -5,6 +5,7 @@ export function CheckBox(aria) {
5
5
  this.rootEl = domNode;
6
6
  this.rootEl.querySelectorAll('.c-checkboxes__conditional').forEach(item => {
7
7
  item.addEventListener('click', this.toggleConditional.bind(this))
8
+ this.toggleConditionalInit(item)
8
9
  })
9
10
 
10
11
  this.rootEl.querySelectorAll('.c-checkboxes__indeterminate-active').forEach(item => {
@@ -12,20 +13,25 @@ export function CheckBox(aria) {
12
13
  })
13
14
  }
14
15
 
16
+ toggleConditionalInit(item) {
17
+ const getInput = item.querySelector('input');
18
+ if(getInput.checked) {
19
+ item.classList.remove('c-checkboxes__conditional-hidden');
20
+ item.classList.add('c-checkboxes__conditional-active');
21
+ } else {
22
+ item.classList.add('c-checkboxes__conditional-hidden');
23
+ item.classList.remove('c-checkboxes__conditional-active');
24
+ }
25
+ }
26
+
15
27
  toggleConditional(event) {
16
28
  const { target: { nodeName, checked, type }, target } = event
17
- if(nodeName === 'INPUT' && type === 'checkbox') {
18
- this.rootEl.querySelectorAll('.c-checkboxes__conditional').forEach(item => {
19
- if(item.contains(target) && checked){
20
- item.classList.remove('c-checkboxes__conditional-hidden')
21
- item.classList.add('c-checkboxes__conditional-active')
22
- }
23
-
24
- if(item.contains(target) && !checked){
25
- item.classList.remove('c-checkboxes__conditional-active')
26
- item.classList.add('c-checkboxes__conditional-hidden')
27
- }
28
- })
29
+ if(nodeName === 'INPUT' && type === 'checkbox' && checked) {
30
+ target.parentElement.parentElement.parentElement.classList.remove('c-checkboxes__conditional-hidden');
31
+ target.parentElement.parentElement.parentElement.classList.add('c-checkboxes__conditional-active');
32
+ } else if (nodeName === 'INPUT' && type === 'checkbox' && !checked) {
33
+ target.parentElement.parentElement.parentElement.classList.add('c-checkboxes__conditional-hidden');
34
+ target.parentElement.parentElement.parentElement.classList.remove('c-checkboxes__conditional-active');
29
35
  }
30
36
  }
31
37
 
@@ -1,42 +1,44 @@
1
1
  export function Collapsible(aria) {
2
-
3
- class Collapsible {
4
- constructor(domNode) {
5
- this.rootEl = domNode;
6
- this.buttonEl = this.rootEl.querySelector('button[aria-expanded]');
7
- this.buttonEl.addEventListener('click', this.toggle.bind(this));
8
- if(domNode.dataset.expanded){
9
- this.buttonEl.click()
10
- }
2
+ aria.collapsibleInit = function (domNode) {
3
+ this.rootEl = domNode;
4
+ this.buttonEl = this.rootEl.querySelector('button[aria-expanded]');
5
+ this.buttonEl.addEventListener('click', handleToggle.bind(this));
6
+ if(this.rootEl.dataset.expanded){
7
+ this.buttonEl.click()
11
8
  }
9
+ };
12
10
 
13
- toggle(event) {
14
- const { target } = event
15
- const elementCollapsibleShow = target.querySelector('.c-collapsible__show')
16
- const elementCollapsibleHide = target.querySelector('.c-collapsible__hide')
17
- const elementCollapsibleContent = target.nextElementSibling
18
-
19
- elementCollapsibleShow.classList.toggle('hidden')
20
- elementCollapsibleHide.classList.toggle('hidden')
21
- elementCollapsibleContent.classList.toggle('hidden')
11
+ function handleToggle(element, isOpen = null) {
12
+ const elementTarget = element.type === 'click' ? element.target : element;
13
+ const elementParent = elementTarget.parentNode;
14
+ const button = element.type === 'click' ? this.buttonEl : element;
15
+ const elementCollapsibleShow = elementTarget.querySelector('.c-collapsible__show')
16
+ const elementCollapsibleHide = elementTarget.querySelector('.c-collapsible__hide')
17
+ const elementCollapsibleContent = elementTarget.nextElementSibling
22
18
 
23
- if(elementCollapsibleShow.classList.contains('hidden')) {
24
- this.buttonEl.setAttribute('aria-expanded', 'true')
25
- elementCollapsibleShow.setAttribute('aria-hidden', 'false')
26
- elementCollapsibleHide.setAttribute('aria-hidden', 'true')
27
- elementCollapsibleContent.setAttribute('aria-hidden', 'false')
28
- } else {
29
- this.buttonEl.setAttribute('aria-expanded', 'false')
30
- elementCollapsibleShow.setAttribute('aria-hidden', 'true')
31
- elementCollapsibleHide.setAttribute('aria-hidden', 'false')
32
- elementCollapsibleContent.setAttribute('aria-hidden', 'true')
33
- }
19
+ if(element.type === 'click' && elementParent.getAttribute('data-expanded') === 'false' || isOpen) {
20
+ elementParent.setAttribute('data-expanded', 'true')
21
+ button.setAttribute('aria-expanded', 'true')
22
+ elementCollapsibleShow.setAttribute('aria-hidden', 'false')
23
+ elementCollapsibleHide.setAttribute('aria-hidden', 'true')
24
+ elementCollapsibleContent.setAttribute('aria-hidden', 'false')
25
+ } else if (element.type === 'click' && !elementParent.getAttribute('data-expanded') === 'true' || !isOpen) {
26
+ elementParent.setAttribute('data-expanded', 'false')
27
+ button.setAttribute('aria-expanded', 'false')
28
+ elementCollapsibleShow.setAttribute('aria-hidden', 'true')
29
+ elementCollapsibleHide.setAttribute('aria-hidden', 'false')
30
+ elementCollapsibleContent.setAttribute('aria-hidden', 'true')
34
31
  }
35
32
  }
36
33
 
37
- const collapsible = document.querySelectorAll('[data-module="c-collapsible"]');
38
- collapsible.forEach((collapsibleElement) => {
39
- new Collapsible(collapsibleElement);
40
- });
41
-
34
+ window.activateItemCollapsible = function (element, isOpen) {
35
+ const collapsible = document.getElementById(element);
36
+ if (collapsible) {
37
+ handleToggle(collapsible, isOpen)
38
+ return [collapsible, isOpen];
39
+ } else {
40
+ console.log('There is no menu with this id in the document.');
41
+ return null;
42
+ }
43
+ };
42
44
  }
@@ -313,6 +313,7 @@ export function dialog(aria) {
313
313
 
314
314
  window.openDialog = function (dialogId, focusAfterClosed, focusFirst) {
315
315
  var dialog = new aria.Dialog(dialogId, focusAfterClosed, focusFirst);
316
+ return [dialogId, focusAfterClosed, focusFirst]
316
317
  };
317
318
 
318
319
  window.closeDialog = function (closeButton) {
@@ -602,6 +602,18 @@ export function listbox(aria) {
602
602
  }
603
603
  };
604
604
 
605
+ window.toggleMenuListbox = function (menuId, open) {
606
+ const getListBoxButton = document.querySelector(`#${menuId} .c-listbox`);
607
+ getListBoxButton.click();
608
+ if(open) {
609
+ getListBoxButton._tippy.popper._tippy.show();
610
+ } else {
611
+ getListBoxButton._tippy.popper._tippy.hide();
612
+ }
613
+
614
+ return [ menuId ]
615
+ }
616
+
605
617
  window.activateItemListBox = function (menuId, activeItemId) {
606
618
  const menu = document.getElementById(menuId);
607
619
  if (menu) {
@@ -610,7 +622,17 @@ export function listbox(aria) {
610
622
  const activeItem = document.querySelector(`#${menuId} #${activeItemId}`);
611
623
  if (activeItem) {
612
624
  activateElement(menuId, activeItemId);
613
- return [menu, activeItem]
625
+ if(typeof activeItemId === 'object') {
626
+ const activeItems = [];
627
+ activeItemId.forEach((item) => {
628
+ const selectItem = document.querySelector(`#${menuId} #${item}`)
629
+ activeItems.push(selectItem);
630
+ })
631
+ return [menu, activeItems]
632
+ } else {
633
+ return [menu, [ activeItem ]]
634
+ }
635
+
614
636
  } else {
615
637
  console.log('There is no element with this id in the menu.');
616
638
  return null;
@@ -3,16 +3,32 @@ export function RadioButton(aria) {
3
3
  class RadioButton {
4
4
  constructor(domNode) {
5
5
  this.rootEl = domNode;
6
- this.rootEl.querySelectorAll('.c-radios__conditional').forEach(item => {
6
+ this.rootEl.querySelectorAll('.c-radios__conditional-active input[type="radio"], .c-radios__conditional-hidden input[type="radio"]').forEach(item => {
7
7
  item.addEventListener('click', this.toggleConditional.bind(this))
8
8
  })
9
9
  }
10
10
 
11
11
  toggleConditional(event) {
12
12
  const { target: { nodeName, type }, target } = event
13
+ const targetParent = target.parentElement.parentElement.parentElement.parentElement;
14
+ const getChildrens = targetParent.querySelectorAll('.c-radios__conditional');
15
+
16
+ if(targetParent && targetParent.classList.contains('c-radios__conditional-active')) {
17
+ return;
18
+ }
19
+
20
+ if(getChildrens.length > 0) {
21
+ getChildrens.forEach(item => {
22
+ if(item.querySelector('input[type="radio"]').checked) {
23
+ item.classList.remove('c-radios__conditional-hidden')
24
+ item.classList.add('c-radios__conditional-active')
25
+ }
26
+ })
27
+ }
28
+
13
29
  if(type === 'radio' && nodeName === 'INPUT') {
14
30
  this.rootEl.querySelectorAll('.c-radios__conditional').forEach(item => {
15
- if(item.contains(target)){
31
+ if(item.querySelector('input[type="radio"]').checked){
16
32
  item.classList.remove('c-radios__conditional-hidden')
17
33
  item.classList.add('c-radios__conditional-active')
18
34
  } else {
@@ -37,6 +37,11 @@ export function toggleComponent(aria) {
37
37
 
38
38
  export function collapsibleComponent(aria) {
39
39
  Collapsible(aria);
40
+
41
+ const collapsibles = document.querySelectorAll('[data-module="c-collapsible"]');
42
+ [...collapsibles].forEach((collapsible) => {
43
+ aria.collapsibleInit(collapsible);
44
+ });
40
45
  }
41
46
 
42
47
  export function dialogComponent(aria) {
@@ -51,6 +51,7 @@
51
51
  },
52
52
  {
53
53
  "name": "con cadenas muy largas",
54
+ "description": "Por defecto, si los items no caben enteros, se truncan y ocupan el espacio de forma equitativa.",
54
55
  "data": {
55
56
  "items": [
56
57
  {
@@ -72,6 +73,31 @@
72
73
  ]
73
74
  }
74
75
  },
76
+ {
77
+ "name": "Último item más largo y con truncado en cadenas largas",
78
+ "description": 'Usa la clase <code>.c-breadcrumbs--truncated</code> para hacer que los items se trunquen solo si tienen mucha anchura (mayor que <code>20rem</code>), como el penúltimo item de este ejemplo. Y que el último item ocupe el espacio restante, truncándose si es necesario, al final, si no le queda espacio suficiente.',
79
+ "data": {
80
+ "classes": "c-breadcrumbs--truncated",
81
+ "items": [
82
+ {
83
+ "text": "Inicio",
84
+ "href": "/"
85
+ },
86
+ {
87
+ "text": "Actividades industriales y energía",
88
+ "href": "/"
89
+ },
90
+ {
91
+ "text": "Ayudas ligadas al autoconsumo, almacenamiento y sistemas térmicos con fuentes de energía renovable renovables",
92
+ "href": "/"
93
+ },
94
+ {
95
+ "text": "Programa 1 Instalaciones de autoconsumo renovable en el sector servicios con o sin almacenamiento",
96
+ "href": "/"
97
+ }
98
+ ]
99
+ }
100
+ },
75
101
  {
76
102
  "name": "Item a mitad sin href",
77
103
  "data": {
@@ -154,7 +180,7 @@
154
180
  },
155
181
  {
156
182
  "name": "con inline en móvil",
157
- "description": "Mirar en anchuras pequeñas para ver cómo se genera un salto de línea si el texto no cabe.",
183
+ "description": 'Usa <code>"inlineOnMobile":true</code> para hacer que los elementos se pongan en linea en móvil en lugar de truncarse. Mirar en anchuras pequeñas para ver cómo se genera un salto de línea si el texto no cabe. Si se quiere también en desktop, usar el parámetro <code>inlineOnDesktop</code>. Ten cuidado con las cadenas largas en mobile: podrían desbordar el viewport, producir scroll horizontal y no cumplir accesibilidad.',
158
184
  "data": {
159
185
  "inlineOnMobile": true,
160
186
  "items": [
@@ -164,23 +190,114 @@
164
190
  },
165
191
  {
166
192
  "text": "Trámites",
167
- "href": "/tramites/"
193
+ "href": "/"
168
194
  },
169
195
  {
170
- "text": "Trámites por tema",
171
- "href": "/tramites/tema/"
196
+ "text": "Categorías de trámites",
197
+ "href": "/"
198
+ },
199
+ {
200
+ "text": "Actividades industriales y energía",
201
+ "href": "/"
202
+ },
203
+ {
204
+ "text": "Actividades industriales",
205
+ "href": "/"
206
+ },
207
+ {
208
+ "text": "Instalaciones industriales",
209
+ "href": "/"
210
+ },
211
+ {
212
+ "text": "Ayudas ligadas al autoconsumo",
213
+ "href": "/"
214
+ },
215
+ {
216
+ "text": "Programa 1 Instalaciones de autoconsumo",
217
+ "href": "/"
218
+ }
219
+ ]
220
+ }
221
+ },
222
+ {
223
+ "name": "con inline en desktop",
224
+ "description": 'Usa <code>"inlineOnDesktop":true</code> para hacer que los elementos se pongan en linea en escritorio y anchuras superiores, en lugar de truncarse. Se genera un salto de línea si el texto no cabe en escritorio, no en mobile. Si se quiere también en mobile, usar el parámetro <code>inlineOnMobile</code>.',
225
+ "data": {
226
+ "inlineOnDesktop": true,
227
+ "items": [
228
+ {
229
+ "text": "Inicio",
230
+ "href": "/"
231
+ },
232
+ {
233
+ "text": "Trámites",
234
+ "href": "/"
235
+ },
236
+ {
237
+ "text": "Categorías de trámites",
238
+ "href": "/"
172
239
  },
173
240
  {
174
241
  "text": "Actividades industriales y energía",
175
- "href": "/tramites/tema/actividades-industriales-y-energia/"
242
+ "href": "/"
176
243
  },
177
244
  {
178
245
  "text": "Actividades industriales",
179
- "href": "/tramites/tema/actividades-industriales/"
246
+ "href": "/"
247
+ },
248
+ {
249
+ "text": "Instalaciones industriales",
250
+ "href": "/"
251
+ },
252
+ {
253
+ "text": "Ayudas ligadas al autoconsumo, almacenamiento y sistemas térmicos con fuentes de energía renovable renovables",
254
+ "href": "/"
180
255
  },
181
256
  {
182
- "text": "Comunicaciones de servicios",
183
- "href": "/tramites/tema/actividades-industriales/comunicaciones-de-servicios/"
257
+ "text": "Programa 1 Instalaciones de autoconsumo renovable en el sector servicios con o sin almacenamiento",
258
+ "href": "/"
259
+ }
260
+ ]
261
+ }
262
+ },
263
+ {
264
+ "name": "con inline en mobile y en desktop",
265
+ "description": 'Usa <code>"inlineOnMobile":true</code> y <code>"inlineOnDesktop":true</code> para hacer que los elementos se pongan en linea en todas las anchuras. Se genera un salto de línea si el texto no cabe en escritorio y en mobile. Ten cuidado con las cadenas largas en mobile: podrían desbordar el viewport, producir scroll horizontal y no cumplir accesibilidad.',
266
+ "data": {
267
+ "inlineOnMobile": true,
268
+ "inlineOnDesktop": true,
269
+ "items": [
270
+ {
271
+ "text": "Inicio",
272
+ "href": "/"
273
+ },
274
+ {
275
+ "text": "Trámites",
276
+ "href": "/"
277
+ },
278
+ {
279
+ "text": "Categorías de trámites",
280
+ "href": "/"
281
+ },
282
+ {
283
+ "text": "Actividades industriales y energía",
284
+ "href": "/"
285
+ },
286
+ {
287
+ "text": "Actividades industriales",
288
+ "href": "/"
289
+ },
290
+ {
291
+ "text": "Instalaciones industriales",
292
+ "href": "/"
293
+ },
294
+ {
295
+ "text": "Ayudas ligadas al autoconsumo",
296
+ "href": "/"
297
+ },
298
+ {
299
+ "text": "Programa 1 Instalaciones de autoconsumo",
300
+ "href": "/"
184
301
  }
185
302
  ]
186
303
  }
@@ -15,7 +15,7 @@
15
15
 
16
16
  .c-breadcrumbs--truncated {
17
17
  li:not(.c-breadcrumbs__backbutton) {
18
- @apply lg:max-w-40;
18
+ @apply lg:max-w-xs;
19
19
 
20
20
  &:last-child {
21
21
  @apply max-w-full;
@@ -51,6 +51,14 @@
51
51
  }
52
52
 
53
53
 
54
+ .c-breadcrumbs--inline-on-desktop {
55
+ li {
56
+ @apply lg:inline;
57
+ @apply lg:leading-loose;
58
+ }
59
+ }
60
+
61
+
54
62
  .c-breadcrumbs__backbutton {
55
63
  @apply mr-sm;
56
64
 
@@ -13,6 +13,10 @@
13
13
  {% set classNames = classNames + " c-breadcrumbs--inline-on-mobile" %}
14
14
  {% endif -%}
15
15
 
16
+ {% if params.inlineOnDesktop %}
17
+ {% set classNames = classNames + " c-breadcrumbs--inline-on-desktop" %}
18
+ {% endif -%}
19
+
16
20
  {# This verbose statement is for Purgecss to match the classnames needed. Purgecss needs explicit entire classnames appear in code, a string concatenation will fail. Eg. lg:grid-cols-max-content-{{ params.items.length if not params.hasBackButton else (params.items.length + 1)}} doesn't compile lg:grid-cols-max-content-1,2,3... #}
17
21
 
18
22
  {% set gridClass %}
@@ -40,7 +44,7 @@ lg:grid-cols-max-content-8{% endif %}
40
44
 
41
45
  <!-- breadcrumbs -->
42
46
  <nav class="{{classNames}}" aria-label="Estás en: "{% for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %}>
43
- <ol class="lg:grid {{ gridClass }} w-full items-baseline text-sm">
47
+ <ol class="{% if not params.inlineOnDesktop %}lg:grid {{ gridClass }}{% endif %} w-full items-baseline text-sm">
44
48
  {% if params.hasBackButton %}
45
49
  <li class="c-breadcrumbs__backbutton flex items-baseline font-bold text-primary-base">
46
50
  <a href="javascript:history.back()" class="px-sm border-r border-neutral-base focus:bg-warning-base focus:outline-none focus:shadow-outline-focus focus:text-black"><span class="sr-only">Volver a la página anterior</span><span aria-hidden="true" title="Volver a la página anterior">&larr;</span></a>
@@ -31,6 +31,10 @@ params:
31
31
  type: boolean
32
32
  required: false
33
33
  description: When true, the breadcrumbs will linebreak if there is needed only on tablet breakpoint and below.
34
+ - name: inlineOnDesktop
35
+ type: boolean
36
+ required: false
37
+ description: When true, the breadcrumbs will linebreak if there is needed only on desktop breakpoint and above.
34
38
  - name: hasBackButton
35
39
  type: boolean
36
40
  required: false
@@ -9,6 +9,13 @@
9
9
  </div>
10
10
  {% endset %}
11
11
 
12
+ {% set fullContent %}
13
+ <h3 class="c-h3"><a href="#" class="c-link c-link--full">Título card</a></h3>
14
+ <div class="prose max-w-none">
15
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sit suscipit mollitia non deleniti illum iure pariatur vel eligendi praesentium in. Velit amet distinctio minima libero dolorem tempora non aliquid? Corporis.</p>
16
+ </div>
17
+ {% endset %}
18
+
12
19
  {% set linksContent %}
13
20
  <h2 class="c-h1">Tus datos médicos e información personal</h2>
14
21
  <ul class="text-lg">
@@ -102,6 +109,15 @@
102
109
  "caller": defaultContent | indent(4)
103
110
  }
104
111
  },
112
+ {
113
+ "name": "todo el card clicable",
114
+ "description": 'Usa la clase <code>.c-link--full</code> en un único enlace dentro del card, junto con las clases <code>relative</code> y <code>hover:bg-neutral-light</code> en el parámetro <code>containerClasses</code> para hacer que el enlace ocupe todo el card y sea perceptible en el estado hover. Recuerda que sólo debe haber un enlace en este tipo de cards clicables.',
115
+ "data": {
116
+ "classes": "lg:w-1/3",
117
+ "containerClasses": "p-base border border-neutral-base rounded relative hover:bg-neutral-light",
118
+ "caller": fullContent | indent(4)
119
+ }
120
+ },
105
121
  {
106
122
  "name": "con icono",
107
123
  "data": {
@@ -1,3 +1,4 @@
1
+ {% from "components/checkboxes/_macro.checkboxes.njk" import componentCheckboxes %}
1
2
  {% from "components/input/_macro.input.njk" import componentInput %}
2
3
 
3
4
  {% macro telefonoContent(id='id') %}
@@ -33,6 +34,44 @@
33
34
  }) }}
34
35
  {% endmacro %}
35
36
 
37
+ {% macro grandchildContent(id='id') %}
38
+ {{ componentCheckboxes({
39
+ "idPrefix": "grandchild-" + id,
40
+ "name": "grandchild-" + id,
41
+ "items": [
42
+ {
43
+ "name": "oficina-principal",
44
+ "id": "oficina-principal-id",
45
+ "value": "oficina-principal",
46
+ "text": "Oficina principal"
47
+ },
48
+ {
49
+ "name": "oficina-secundaria",
50
+ "id": "oficina-secundaria-id",
51
+ "value": "oficina-secundaria",
52
+ "text": "Oficina secundaria"
53
+ }
54
+ ]
55
+ }) }}
56
+ {% endmacro %}
57
+
58
+ {% macro nestedContent(id='id') %}
59
+ {{ componentCheckboxes({
60
+ "idPrefix": "with-conditional-items-checked-nested-" + id,
61
+ "name": "with-conditional-items-checked-nested-" + id,
62
+ "items": [
63
+ {
64
+ "value": "oficinas-de-registro",
65
+ "text": "Oficinas de registro",
66
+ "checked": true,
67
+ "conditional": {
68
+ "html": grandchildContent(id).val
69
+ }
70
+ }
71
+ ]
72
+ }) }}
73
+ {% endmacro %}
74
+
36
75
 
37
76
 
38
77
  {% set exampleComponent = "checkboxes" %}
@@ -519,6 +558,29 @@
519
558
  ]
520
559
  }
521
560
  },
561
+ {
562
+ "name": "con items condicionales anidados",
563
+ "data": {
564
+ "idPrefix": "with-conditional-nested-items",
565
+ "name": "with-conditional-nested-items",
566
+ "idPrefix": "how-contacted-nested",
567
+ "fieldset": {
568
+ "legend": {
569
+ "text": "¿Cómo quieres que te contactemos?"
570
+ }
571
+ },
572
+ "items": [
573
+ {
574
+ "value": "presencial",
575
+ "text": "Presencial",
576
+ "checked": true,
577
+ "conditional": {
578
+ "html": nestedContent('1').val
579
+ }
580
+ }
581
+ ]
582
+ }
583
+ },
522
584
  {
523
585
  "name": "con item condicional seleccionado",
524
586
  "data": {
@@ -3,7 +3,7 @@
3
3
  {
4
4
  "name": "por defecto",
5
5
  "data": {
6
- "id": "collapsible-example",
6
+ "id": "collapsible-default",
7
7
  "headerText": "Cabecera del collapsible",
8
8
  "text": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
9
9
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
@@ -15,8 +15,9 @@
15
15
  },
16
16
  {
17
17
  "name": "expandido",
18
+ "description": 'Añade <code>open: true</code> a un item para mostrarlo abierto inicialmente.',
18
19
  "data": {
19
- "id": "help-with-nationality",
20
+ "id": "collapsible-initially-expanded",
20
21
  "headerText": "Cabecera del collapsible",
21
22
  "text": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
22
23
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
@@ -27,10 +28,24 @@
27
28
  "open": true
28
29
  }
29
30
  },
31
+ {
32
+ "name": "expandido con JavaScript",
33
+ "description": 'También puedes usar con javascript la función global <code>activateItemCollapsible(element, open)</code>, para mostrar un item abierto o cerrado, usando su id, el parámetro <code>open</code> admite <code>true</code> o <code>false</code>, si le pasamos true se mostrará abierto, y si le pasamos false se mostrará cerrado. Ej: Abre la consola del navegador y escribe <code>activateItemCollapsible("collapsible-expanded-title", true)</code> para mostrar el item actual abierto.',
34
+ "data": {
35
+ "id": "collapsible-expanded",
36
+ "headerText": "Cabecera del collapsible",
37
+ "text": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
38
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
39
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
40
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
41
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
42
+ proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
43
+ }
44
+ },
30
45
  {
31
46
  "name": "con HTML",
32
47
  "data": {
33
- "id": "collapsible-html-example",
48
+ "id": "collapsible-html",
34
49
  "headerText": "Cabecera del collapsible",
35
50
  "html": '<p>Lorem ipsum dolor sit amet, <strong>consectetur</strong> adipisicing elit, sed do eiusmod
36
51
  tempor <em>incididunt</em> ut labore et dolore magna aliqua. Ut enim ad minim veniam,
@@ -40,4 +55,4 @@
40
55
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
41
56
  }
42
57
  }
43
- ] %}
58
+ ] %}
@@ -0,0 +1,33 @@
1
+ /* ==========================================================================
2
+ _styles.collapsible.css
3
+ ========================================================================== */
4
+
5
+ @layer components {
6
+ .c-collapsible[data-expanded="true"] {
7
+ .c-collapsible__show {
8
+ @apply hidden;
9
+ }
10
+
11
+ .c-collapsible__hide {
12
+ @apply block;
13
+ }
14
+
15
+ .c-collapsible__content{
16
+ @apply block;
17
+ }
18
+ }
19
+
20
+ .c-collapsible[data-expanded="false"] {
21
+ .c-collapsible__show {
22
+ @apply block;
23
+ }
24
+
25
+ .c-collapsible__hide {
26
+ @apply hidden;
27
+ }
28
+
29
+ .c-collapsible__content{
30
+ @apply hidden;
31
+ }
32
+ }
33
+ }
@@ -1,10 +1,10 @@
1
1
  <!-- collapsible -->
2
- <div class="{%- if params.classes %} {{ params.classes }}{% else -%} -my-px py-sm border-t border-b border-neutral-base{% endif %} c-collapsible" {%- for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %} {% if params.open %} data-expanded="true" {% endif %} data-module="c-collapsible">
2
+ <div class="{%- if params.classes %} {{ params.classes }}{% else -%} -my-px py-sm border-t border-b border-neutral-base{% endif %} c-collapsible" {%- for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %} {% if params.open %} data-expanded="false" {% else %} data-expanded="true" {% endif %} data-module="c-collapsible">
3
3
  <button aria-expanded="false" {%- if params.id %} id="{{params.id}}-title"{% endif %} class="group relative w-full py-sm font-semibold text-left cursor-pointer focus:bg-warning-base focus:outline-none focus:shadow-outline-focus focus:text-black" {%- if params.id %} aria-controls="{{params.id}}"{% endif %}>{{ params.headerHtml | safe if params.headerHtml else params.headerText }}
4
- <span class="c-collapsible__show absolute inset-y-0 right-0 py-sm font-normal text-sm text-neutral-dark underline group-focus:text-black pointer-events-none " aria-hidden="false">Mostrar</span>
5
- <span class="c-collapsible__hide absolute inset-y-0 right-0 py-sm font-normal text-sm text-neutral-dark underline group-focus:text-black pointer-events-none hidden" aria-hidden="true">Ocultar</span>
4
+ <span class="c-collapsible__show absolute inset-y-0 right-0 py-sm font-normal text-sm text-neutral-dark underline group-focus:text-black pointer-events-none" aria-hidden="false">Mostrar</span>
5
+ <span class="c-collapsible__hide absolute inset-y-0 right-0 py-sm font-normal text-sm text-neutral-dark underline group-focus:text-black pointer-events-none" aria-hidden="true">Ocultar</span>
6
6
  </button>
7
- <div aria-hidden="true" class="c-collapsible__content hidden py-sm" {%- if params.id %} id="{{params.id}}"{% endif %}>
7
+ <div aria-hidden="true" class="c-collapsible__content py-sm" {%- if params.id %} id="{{params.id}}"{% endif %}>
8
8
  {% if params.html %}
9
9
  {{ params.html | safe }}
10
10
  {% else %}
@@ -14,4 +14,4 @@
14
14
  {% endif %}
15
15
  </div>
16
16
  </div>
17
- <!-- /collapsible -->
17
+ <!-- /collapsible -->
@@ -49,6 +49,27 @@
49
49
  }) }}
50
50
  {% endset %}
51
51
 
52
+ {% set javascriptExample %}
53
+ {{ componentModal({
54
+ "id": "javascript-action-example",
55
+ "title": {
56
+ "text": "Servicio publicado"
57
+ },
58
+ "description": {
59
+ "html": "Actualmente este servicio está publicado. <br>Los cambios realizados no serán visibles hasta que sean validados"
60
+ },
61
+ "itemsSecondary": [
62
+ {
63
+ "html": 'Cerrar',
64
+ "attributes": {
65
+ "onclick": "closeDialog(this)"
66
+ }
67
+ }
68
+ ],
69
+ "isDismissible": true
70
+ }) }}
71
+ {% endset %}
72
+
52
73
 
53
74
  {% set exampleComponent = "dialog" %}
54
75
  {% set examples = [
@@ -59,7 +80,8 @@
59
80
  "button": {
60
81
  "text": "Abrir modal",
61
82
  "attributes": {
62
- "onclick": "openDialog('default', this, 'label-default-example')"
83
+ "onclick": "openDialog('default', this, 'label-default-example')",
84
+ "id": "button-label-default-example"
63
85
  }
64
86
  },
65
87
  "id": "default",
@@ -78,7 +100,8 @@
78
100
  "button": {
79
101
  "text": "Abrir modal con acciones secundarias",
80
102
  "attributes": {
81
- "onclick": "openDialog('secondary', this, 'label-secondary-action-example')"
103
+ "onclick": "openDialog('secondary', this, 'label-secondary-action-example')",
104
+ "id": "button-label-secondary-action-example"
82
105
  }
83
106
  },
84
107
  "id": "secondary",
@@ -90,5 +113,26 @@
90
113
  },
91
114
  "caller": secondaryExample
92
115
  }
116
+ },
117
+ {
118
+ "name": "Modal lanzado con un Dialog con JavaScript",
119
+ "description": 'También puedes usar con javascript la función global <code>openDialog(dialog, focusAfterClosed, focusFirst)</code>, para abrir la modal usando su id. La función admite tres parámetros <code>dialog</code>, que es el id de la modal que queremos abrir, <code>focusAfterClosed</code>, el elemento que tendrá el foco cuando cerremos la modal, y <code>focusFirst</code>, el elemento que tendra el foco al abrir la modal. Ej: Abre la consola del navegador y escribe <code>openDialog("modal-javascript", "button-javascript-action-example", "label-javascript-action-example")</code> para mostrar la modal.',
120
+ "data": {
121
+ "button": {
122
+ "text": "Abrir modal con JavaScript",
123
+ "attributes": {
124
+ "onclick": "openDialog('modal-javascript', this, 'label-javascript-action-example')",
125
+ "id": "button-javascript-action-example"
126
+ }
127
+ },
128
+ "id": "modal-javascript",
129
+ "classes": "hidden lg:absolute lg:inset-0 min-h-screen",
130
+ "attributes": {
131
+ "role": "dialog",
132
+ "aria-labelledby": "javascript-action-example",
133
+ "aria-modal": true
134
+ },
135
+ "caller": javascriptExample
136
+ }
93
137
  }
94
- ] %}
138
+ ] %}
@@ -1,7 +1,7 @@
1
1
  <!-- header__offcanvas -->
2
2
  <div id="header-offcanvas" class="hidden" role="dialog" aria-labelledby="header-offcanvas-button-text" aria-modal="true">
3
3
  <div class="left-0 fixed top-0 h-[100dvh] w-offcanvas ml-offcanvas-negative">
4
- <div class="h-full overflow-auto relative h-screen bg-white z-10">
4
+ <div class="h-full overflow-auto relative bg-white z-10">
5
5
  <div class="text-right p-sm">
6
6
  <button
7
7
  onclick="closeDialog(this)"
@@ -122,8 +122,7 @@
122
122
  {% if params.offcanvas %}
123
123
  {% set offcanvasContent %}
124
124
  {% call componentOffcanvas({
125
- text: params.offcanvas.textClose,
126
- labelledId: params.offcanvas.labelledId
125
+ text: params.offcanvas.textClose
127
126
  }) %}
128
127
  {% if caller %}
129
128
  {{ caller() }} {#- if statement allows usage of `call` to be optional -#}
@@ -13,7 +13,7 @@ params:
13
13
  description: This is an area over the title
14
14
  - name: logo
15
15
  type: object
16
- required: true
16
+ required: false
17
17
  description: options for the logo element
18
18
  - name: url
19
19
  type: string
@@ -57,7 +57,7 @@ params:
57
57
  description: If `true` the title area will be hidden.
58
58
  - name: titleContainer
59
59
  type: object
60
- required: true
60
+ required: false
61
61
  description: params for the container that holds the logo, title and subtitle.
62
62
  - name: backgroundColor
63
63
  type: string
@@ -265,7 +265,7 @@ params:
265
265
  description: This is an area over the title
266
266
  - name: logo
267
267
  type: object
268
- required: true
268
+ required: false
269
269
  description: options for the logo element
270
270
  - name: url
271
271
  type: string
@@ -9,7 +9,7 @@
9
9
  {% set examples = [
10
10
  {
11
11
  "name": "por defecto",
12
- "description": "This is the mini header.",
12
+ "description": "Este es el mini header por defecto. Una barra con logo del Gobierno de Aragón que enlaza al portal de la administración. Deberían usarse en todos los sitios web que tengan subdominio aragon.es.",
13
13
  "data": {
14
14
  }
15
15
  },
@@ -18,8 +18,8 @@ params:
18
18
  - name: classes
19
19
  type: string
20
20
  required: false
21
- description: Classes to add to the skip link.
21
+ description: Classes to add to the header-mini.
22
22
  - name: attributes
23
23
  type: object
24
24
  required: false
25
- description: HTML attributes (for example data attributes) to add to the skip link.
25
+ description: HTML attributes (for example data attributes) to add to the header-mini.
@@ -615,5 +615,42 @@
615
615
  }
616
616
  ]
617
617
  }
618
+ },
619
+ {
620
+ "name": "Menú abierto o cerrado con Javascript",
621
+ "description": 'Podemos abrir o cerrar un menú usando con javascript la función global <code>toggleMenuListbox(elementMenu, open)</code> para abrir o cerrar un menú, usando su id. El parámetro <code>open</code> admite <code>true</code> o <code>false</code>, si le pasamos <code>true</code> abrirá el menú, y si le pasamos <code>false</code> cerrará el menú. Ej: Abre la consola del navegador y escribe <code>toggleMenuListbox("listbox-javascript", true)</code> para abrir el menú de este ejemplo.',
622
+ "data": {
623
+ "id": "with-active-item",
624
+ "text": "con item activo",
625
+ "label": {
626
+ "text": "Esto es un label"
627
+ },
628
+ "items": [
629
+ {
630
+ "href": "#",
631
+ "text": "Opción 1"
632
+ },
633
+ {
634
+ "href": "#",
635
+ "text": "Opción 2"
636
+ },
637
+ {
638
+ "href": "#",
639
+ "text": "Opción 3"
640
+ },
641
+ {
642
+ "href": "#",
643
+ "text": "Opción 4"
644
+ },
645
+ {
646
+ "href": "#",
647
+ "text": "Opción 5",
648
+ "active": true
649
+ }
650
+ ],
651
+ "attributes": {
652
+ "id": "listbox-javascript"
653
+ }
654
+ }
618
655
  }
619
656
  ] %}
@@ -49,7 +49,7 @@
49
49
  {%- endif %}
50
50
  {% set commonSubItemAttributes %}{% if subId %} id="{{ subId }}"{% endif %} {%- if subitem.title %} title="{{ subitem.title }}"{% endif %} {%- for attribute, value in subitem.attributes %} {{ attribute }}="{{ value }}"{% endfor %}{% endset %}
51
51
  <li>
52
- <a aria-current="{%- if subitem.active %}true{% else %}false{% endif -%}" {%- if subitem.id %} id="{{ subId }}"{% endif %} href="{{ subitem.href }}" class="flex items-center px-base py-sm text-sm hover:bg-primary-base hover:text-white focus:bg-warning-base focus:outline-none focus:shadow-outline-focus focus:text-black{%- if subitem.classes %} {{ subitem.classes }}{% endif -%} {%- if subitem.disabled %} pointer-events-none{% endif -%}" {%- if subitem.disabled %} tabindex="-1"{% endif -%} {%- if subitem.target %} target="{{ subitem.target }}"{% endif %} {{- commonSubItemAttributes | safe }}>
52
+ <a {%- if subitem.active %} aria-current="page"{% endif %} {%- if subitem.id %} id="{{ subId }}"{% endif %} href="{{ subitem.href }}" class="flex items-center px-base py-sm text-sm hover:bg-primary-base hover:text-white focus:bg-warning-base focus:outline-none focus:shadow-outline-focus focus:text-black{%- if subitem.classes %} {{ subitem.classes }}{% endif -%} {%- if subitem.disabled %} pointer-events-none{% endif -%}" {%- if subitem.disabled %} tabindex="-1"{% endif -%} {%- if subitem.target %} target="{{ subitem.target }}"{% endif %} {{- commonSubItemAttributes | safe }}>
53
53
  {{ subitem.html | safe if subitem.html else subitem.text }}
54
54
  {% if subitem.disabled %}
55
55
  <svg viewBox="0 0 140 140" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" class="inline-block align-middle ml-sm text-neutral-base fill-current" aria-hidden="true" focusable="false" ><path d="M70 0a70 70 0 1070 70A70.08 70.08 0 0070 0zM20 70a50 50 0 0174.8-43.4 2.51 2.51 0 011.23 1.84 2.48 2.48 0 01-.71 2.1L30.54 95.32a2.51 2.51 0 01-3.94-.52A49.63 49.63 0 0120 70zm100 0a50 50 0 01-74.8 43.4 2.51 2.51 0 01-1.23-1.84 2.48 2.48 0 01.71-2.1l64.78-64.78a2.51 2.51 0 013.94.52A49.63 49.63 0 01120 70z"/></svg>
@@ -1,4 +1,5 @@
1
1
  {% from "components/input/_macro.input.njk" import componentInput %}
2
+ {% from "components/radios/_macro.radios.njk" import componentRadios %}
2
3
 
3
4
  {% macro telefonoContent(id='id') %}
4
5
  {{ componentInput({
@@ -33,6 +34,52 @@
33
34
  }) }}
34
35
  {% endmacro %}
35
36
 
37
+ {% macro grandchildContent(id='id') %}
38
+ {{ componentRadios({
39
+ "idPrefix": "grandchild-" + id,
40
+ "name": "grandchild-" + id,
41
+ "items": [
42
+ {
43
+ "name": "oficina-principal-" + id,
44
+ "id": "oficina-principal-id-" + id,
45
+ "value": "oficina-principal-" + id,
46
+ "checked": true,
47
+ "html": "Oficina principal"
48
+ },
49
+ {
50
+ "name": "oficina-secundaria-" + id,
51
+ "id": "oficina-secundaria-id-" + id,
52
+ "value": "oficina-secundaria-" + id,
53
+ "html": "Oficina secundaria"
54
+ }
55
+ ]
56
+ }) }}
57
+ {% endmacro %}
58
+
59
+ {% macro nestedContent(id='id') %}
60
+ {{ componentRadios({
61
+ "idPrefix": "with-conditional-items-checked-nested-" + id,
62
+ "name": "with-conditional-items-checked-nested-" + id,
63
+ "items": [
64
+ {
65
+ "value": "oficinas-de-registro",
66
+ "text": "Oficinas de registro",
67
+ "checked": true,
68
+ "conditional": {
69
+ "html": grandchildContent('oficinas-de-registro-' + id).val
70
+ }
71
+ },
72
+ {
73
+ "value": "oficinas-locales",
74
+ "text": "Oficinas locales",
75
+ "conditional": {
76
+ "html": grandchildContent('oficinas-locales-' + id).val
77
+ }
78
+ }
79
+ ]
80
+ }) }}
81
+ {% endmacro %}
82
+
36
83
  {% set exampleComponent = "radios" %}
37
84
  {% set examples = [
38
85
  {
@@ -415,10 +462,33 @@
415
462
  },
416
463
  {
417
464
  "value": "mensaje-SMS",
418
- "text": "Mensaje SMS",
465
+ "text": "Sin conditional"
466
+ }
467
+ ]
468
+ }
469
+ },
470
+ {
471
+ "name": "con items condicionales anidados",
472
+ "data": {
473
+ "idPrefix": "with-conditional-nested-items",
474
+ "name": "with-conditional-nested-items",
475
+ "fieldset": {
476
+ "legend": {
477
+ "text": "¿Cómo quieres que te contactemos?"
478
+ }
479
+ },
480
+ "items": [
481
+ {
482
+ "value": "presencial",
483
+ "text": "Presencial",
484
+ "checked": true,
419
485
  "conditional": {
420
- "html": mobileContent('2').val
486
+ "html": nestedContent('1').val
421
487
  }
488
+ },
489
+ {
490
+ "value": "telefono",
491
+ "text": "Por teléfono"
422
492
  }
423
493
  ]
424
494
  }