wagtail-enap-designsystem 1.2.1.192__py3-none-any.whl → 1.2.1.194__py3-none-any.whl

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.

Potentially problematic release.


This version of wagtail-enap-designsystem might be problematic. Click here for more details.

Files changed (25) hide show
  1. enap_designsystem/blocks/content_blocks.py +11 -0
  2. enap_designsystem/blocks/semana_inovacao.py +1 -1
  3. enap_designsystem/migrations/0465_alter_areaaluno_body_alter_cursoeadpage_curso_and_more.py +64768 -0
  4. enap_designsystem/migrations/0466_carouselresponsivo_largura_container.py +29 -0
  5. enap_designsystem/models.py +2 -2
  6. enap_designsystem/static/enap_designsystem/blocks/banner_topicos_block.css +1 -1
  7. enap_designsystem/static/enap_designsystem/blocks/btn.css +23 -2
  8. enap_designsystem/static/enap_designsystem/blocks/capsulas.css +222 -74
  9. enap_designsystem/static/enap_designsystem/blocks/carousel_images.css +3 -1
  10. enap_designsystem/static/enap_designsystem/blocks/carousel_responsive.css +9 -27
  11. enap_designsystem/static/enap_designsystem/blocks/carousel_responsivo_snippet.css +19 -27
  12. enap_designsystem/static/enap_designsystem/blocks/semana.css +0 -1
  13. enap_designsystem/static/enap_designsystem/blocks/texto_imagem.css +0 -1
  14. enap_designsystem/templates/enap_designsystem/base.html +0 -4
  15. enap_designsystem/templates/enap_designsystem/blocks/carousel_responsivo_snippet.html +90 -54
  16. enap_designsystem/templates/enap_designsystem/blocks/legislacao_block.html +1 -1
  17. enap_designsystem/templates/enap_designsystem/blocks/richtext_block.html +116 -48
  18. enap_designsystem/templates/enap_designsystem/pages/capsula_index_page.html +62 -54
  19. enap_designsystem/templates/enap_designsystem/pages/capsula_page.html +213 -50
  20. enap_designsystem/views.py +2 -2
  21. {wagtail_enap_designsystem-1.2.1.192.dist-info → wagtail_enap_designsystem-1.2.1.194.dist-info}/METADATA +1 -1
  22. {wagtail_enap_designsystem-1.2.1.192.dist-info → wagtail_enap_designsystem-1.2.1.194.dist-info}/RECORD +25 -23
  23. {wagtail_enap_designsystem-1.2.1.192.dist-info → wagtail_enap_designsystem-1.2.1.194.dist-info}/WHEEL +0 -0
  24. {wagtail_enap_designsystem-1.2.1.192.dist-info → wagtail_enap_designsystem-1.2.1.194.dist-info}/licenses/LICENSE +0 -0
  25. {wagtail_enap_designsystem-1.2.1.192.dist-info → wagtail_enap_designsystem-1.2.1.194.dist-info}/top_level.txt +0 -0
@@ -197,64 +197,72 @@
197
197
  {% if capsulas %}
198
198
  <div class="recursos-grid">
199
199
  {% for capsula in capsulas %}
200
- <article class="recurso-card">
201
- <div class="recurso-card-icone">
202
- <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
203
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
204
- </svg>
205
- </div>
206
-
207
- <h2 class="recurso-card-titulo">
208
- <a href="{% pageurl capsula %}">{{ capsula.title }}</a>
209
- </h2>
210
-
211
- <p class="recurso-card-descricao">
212
- {{ capsula.resumo_card|default:"Aprenda sobre este importante aspecto da acessibilidade digital." }}
213
- </p>
214
-
215
- {# Tags de deficiência #}
216
- {% if capsula.tipos_deficiencia %}
217
- <div class="recurso-tags-categoria">
218
- {% for tipo in capsula.get_tipos_deficiencia_display|slice:":2" %}
219
- <span class="tag-categoria">
220
- <svg class="tag-categoria-icone" fill="currentColor" viewBox="0 0 20 20">
221
- <circle cx="10" cy="10" r="4"></circle>
222
- </svg>
223
- {{ tipo }}
224
- </span>
225
- {% endfor %}
226
- </div>
227
- {% endif %}
228
-
229
- {# Badge de prioridade #}
230
- {% if capsula.prioridade %}
231
- <div class="recurso-badge recurso-badge-{{ capsula.prioridade }}">
232
- <svg class="badge-icone" fill="currentColor" viewBox="0 0 20 20">
233
- <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
200
+ <article class="recurso-card">
201
+ <!-- Link principal que envolve todo o card -->
202
+ <a href="{% pageurl capsula %}" class="recurso-card-link" aria-labelledby="card-titulo-{{ forloop.counter }}">
203
+ <span class="sr-only">Acessar cápsula: {{ capsula.title }}</span>
204
+
205
+
206
+ <div class="recurso-card-icone">
207
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
208
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
234
209
  </svg>
235
- {{ capsula.get_prioridade_display }}
236
210
  </div>
237
- {% endif %}
238
-
239
- {# Tags de recurso #}
240
- {% if capsula.tipos_recurso %}
241
- <div class="recurso-tags-tipo">
242
- {% for recurso in capsula.get_tipos_recurso_display|slice:":3" %}
243
- <span class="tag-tipo">
244
- <svg class="tag-tipo-icone" fill="currentColor" viewBox="0 0 20 20">
245
- <path fill-rule="evenodd" d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z" clip-rule="evenodd"></path>
246
- </svg>
247
- {{ recurso }}
248
- </span>
249
- {% endfor %}
211
+
212
+ <h2 class="recurso-card-titulo" id="card-titulo-{{ forloop.counter }}">
213
+ {{ capsula.title }}
214
+ </h2>
215
+
216
+ <p class="recurso-card-descricao">
217
+ {{ capsula.resumo_card|default:"Aprenda sobre este importante aspecto da acessibilidade digital." }}
218
+ </p>
219
+
220
+ {# Tags de deficiência #}
221
+ {% if capsula.tipos_deficiencia %}
222
+ <div class="recurso-tags-categoria" aria-label="Tipos de deficiência abordados">
223
+ {% for tipo in capsula.get_tipos_deficiencia_display|slice:":2" %}
224
+ <span class="tag-categoria">
225
+ <svg class="tag-categoria-icone" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
226
+ <circle cx="10" cy="10" r="4"></circle>
227
+ </svg>
228
+ {{ tipo }}
229
+ </span>
230
+ {% endfor %}
231
+ </div>
232
+ {% endif %}
233
+
234
+ {# Badge de prioridade #}
235
+ {% if capsula.prioridade %}
236
+ <div class="recurso-badge recurso-badge-{{ capsula.prioridade }}" aria-label="Nível de prioridade">
237
+ <svg class="badge-icone" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
238
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
239
+ </svg>
240
+ {{ capsula.get_prioridade_display }}
241
+ </div>
242
+ {% endif %}
243
+
244
+ {# Tags de recurso #}
245
+ {% if capsula.tipos_recurso %}
246
+ <div class="recurso-tags-tipo" aria-label="Tipos de recurso">
247
+ {% for recurso in capsula.get_tipos_recurso_display|slice:":3" %}
248
+ <span class="tag-tipo">
249
+ <svg class="tag-tipo-icone" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
250
+ <path fill-rule="evenodd" d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z" clip-rule="evenodd"></path>
251
+ </svg>
252
+ {{ recurso }}
253
+ </span>
254
+ {% endfor %}
255
+ </div>
256
+ {% endif %}
257
+
258
+ <div class="recurso-card-botao-wrapper">
259
+ <span class="recurso-card-botao">
260
+ Acessar Cápsula
261
+ </span>
250
262
  </div>
251
- {% endif %}
252
-
253
- <a href="{% pageurl capsula %}" class="recurso-card-botao">
254
- Acessar Cápsula
255
263
  </a>
256
- </article>
257
- {% endfor %}
264
+ </article>
265
+ {% endfor %}
258
266
  </div>
259
267
 
260
268
  {% else %}
@@ -72,7 +72,7 @@
72
72
  </span>
73
73
  <h1 class="capsulas-hero__title">{{ page.title }}</h1>
74
74
  <p class="capsulas-hero__description">{{ page.resumo_card }}</p>
75
- <a href="#content" class="capsulas-hero__cta">Explorar Conteúdo</a>
75
+ <a href="#content" class="capsulas-hero__cta" aria-label="Explorar o conteúdo da cápsula">Explorar Conteúdo</a>
76
76
  </div>
77
77
  <div class="capsulas-hero__illustration">
78
78
  <img src="https://42f2671d685f51e10fc6-b9fcecea3e50b3b59bdc28dead054ebc.ssl.cf5.rackcdn.com/illustrations/Visually_impaired_re_mtrb.svg" alt="Ilustração de acessibilidade" class="capsulas-hero__image">
@@ -80,14 +80,14 @@
80
80
  </div>
81
81
  </section>
82
82
 
83
- <div class="capsulas-tab-navigation" id="tabNavigation">
83
+ <div class="capsulas-tab-navigation" id="tabNavigation" role="navigation" aria-label="Navegação por tópicos">
84
84
  <div class="capsulas-tabs-container">
85
- <button class="capsulas-tab-arrow capsulas-tab-arrow--prev" id="prev-tab">
86
- <i class="fas fa-chevron-left"></i>
85
+ <button class="capsulas-tab-arrow capsulas-tab-arrow--prev" id="prev-tab" aria-label="Navegar para abas anteriores">
86
+ <i class="fas fa-chevron-left" aria-hidden="true"></i>
87
87
  </button>
88
88
  <div class="capsulas-tabs-scroll" id="tabs-scroll">
89
89
  <ul class="capsulas-tabs">
90
- <li><button class="capsulas-tab-item capsulas-tab-item--active" data-target="section-what">O que é</button></li>
90
+ <li><button class="capsulas-tab-item capsulas-tab-item--active" data-target="section-what" aria-current="true">O que é</button></li>
91
91
  <li><button class="capsulas-tab-item" data-target="section-why">Por que é importante</button></li>
92
92
  <li><button class="capsulas-tab-item" data-target="section-when">Quando utilizar</button></li>
93
93
  <li><button class="capsulas-tab-item" data-target="section-how">Como aplicar</button></li>
@@ -103,42 +103,44 @@
103
103
  </div>
104
104
  </div>
105
105
 
106
- <div id="content" class="capsulas-main-content">
106
+ <div id="content" class="capsulas-main-content"role="main">
107
107
  <!-- O que é? -->
108
108
  <section id="section-what" class="capsulas-content-section">
109
109
  <div class="capsulas-container">
110
110
  <div class="capsulas-two-column">
111
111
  <div>
112
- <h2 class="capsulas-section-title-caps">O que é?</h2>
112
+ <h2 class="capsulas-section-title-caps-dark">O que é?</h2>
113
113
  {{ page.o_que_e_resumo|safe }}
114
114
  {% if page.o_que_e_detalhado %}
115
115
  <div style="margin-top: 2rem;">
116
- <button class="capsulas-btn capsulas-btn--primary" onclick="toggleAccordion('detail-what')">
117
- Ver detalhes <i class="fa-solid fa-circle-chevron-right"></i>
116
+ <button class="capsulas-btn capsulas-btn--primary" onclick="toggleAccordion('detail-what')" aria-expanded="false" aria-controls="detail-what">
117
+ Ver detalhes <i class="fa-solid fa-circle-chevron-right" aria-hidden="true"></i>
118
118
  </button>
119
119
  </div>
120
120
  {% endif %}
121
121
  </div>
122
122
 
123
- <div class="capsulas-modern-icon-card">
124
- <div class="capsulas-icon-blob">
125
- <i class="fas fa-question-circle capsulas-section-icon"></i>
123
+ <div class="capsulas-modern-icon-card" aria-hidden="true">
124
+ <div class="capsulas-illustration">
125
+ <img class="capsulas-illustration" src="https://42f2671d685f51e10fc6-b9fcecea3e50b3b59bdc28dead054ebc.ssl.cf5.rackcdn.com/illustrations/Questions_re_1fy7.svg"
126
+ alt="Ilustração representando o conceito da seção 'O que é'"
127
+ width="240"
128
+ height="240">
126
129
  </div>
127
- <div class="capsulas-icon-background"></div>
128
130
  </div>
129
131
  </div>
130
132
 
131
133
  {% if page.o_que_e_detalhado %}
132
134
  <div id="detail-what" class="capsulas-accordion">
133
- <div class="capsulas-accordion__header" onclick="toggleAccordion('detail-what')">
135
+ <div class="capsulas-accordion__header" onclick="toggleAccordion('detail-what')" role="button" aria-expanded="false" aria-controls="detail-what" tabindex="0">
134
136
  <h3 class="capsulas-accordion__title">
135
137
  <div class="capsulas-accordion__icon">
136
- <i class="fas fa-info-circle"></i>
138
+ <i class="fas fa-info-circle" aria-hidden="true"></i>
137
139
  </div>
138
140
  Conteúdo Detalhado
139
141
  </h3>
140
142
  <div class="capsulas-accordion__toggle">
141
- <i class="fas fa-chevron-down"></i>
143
+ <i class="fas fa-chevron-down" aria-hidden="true"></i>
142
144
  </div>
143
145
  </div>
144
146
  <div class="capsulas-accordion__body">
@@ -150,7 +152,7 @@
150
152
  </section>
151
153
 
152
154
  <!-- Por que é importante? -->
153
- <section id="section-why" class="capsulas-content-section">
155
+ <section id="section-why" class=" capsulas-content-section-why">
154
156
  <div class="capsulas-container">
155
157
  <div class="capsulas-two-column">
156
158
  <div class="capsulas-illustration-card">
@@ -159,7 +161,7 @@
159
161
 
160
162
  <div>
161
163
  <div class="capsulas-section-header">
162
- <h2 class="capsulas-section-title-caps">Por que é importante?</h2>
164
+ <h2 class="capsulas-section-title-caps-dark">Por que é importante?</h2>
163
165
  </div>
164
166
 
165
167
  {{ page.por_que_importante_resumo|safe }}
@@ -199,9 +201,10 @@
199
201
  <section id="section-when" class="capsulas-content-section">
200
202
  <div class="capsulas-container">
201
203
  <div class="capsulas-section-header">
202
- <h2 class="capsulas-section-title-caps">Quando utilizar?</h2>
204
+ <h2 class="capsulas-section-title-caps-dark">Quando utilizar?</h2>
205
+ {{ page.quando_utilizar_resumo|safe }}
203
206
  </div>
204
- {{ page.quando_utilizar_resumo|safe }}
207
+
205
208
 
206
209
  <div class="capsulas-icon-container">
207
210
  <div class="capsulas-modern-icon-card">
@@ -224,7 +227,7 @@
224
227
  <div class="capsulas-two-column">
225
228
  <div>
226
229
  <div class="capsulas-section-header">
227
- <h2 class="capsulas-section-title-caps">Como aplicar?</h2>
230
+ <h2 class="capsulas-section-title-caps-white">Como aplicar?</h2>
228
231
  </div>
229
232
  {{ page.como_aplicar_resumo|safe }}
230
233
 
@@ -267,7 +270,7 @@
267
270
  <section id="section-check" class="capsulas-content-section">
268
271
  <div class="capsulas-container">
269
272
  <div class="capsulas-section-header">
270
- <h2 class="capsulas-section-title-caps">Método de verificação</h2>
273
+ <h2 class="capsulas-section-title-caps-dark">Método de verificação</h2>
271
274
  <p class="capsulas-section-description">Saiba como verificar se o padrão foi corretamente implementado.</p>
272
275
  </div>
273
276
 
@@ -292,7 +295,7 @@
292
295
  <section id="section-examples" class="capsulas-content-section">
293
296
  <div class="capsulas-container">
294
297
  <div class="capsulas-section-header">
295
- <h2 class="capsulas-section-title-caps">Exemplos</h2>
298
+ <h2 class="capsulas-section-title-caps-white">Exemplos</h2>
296
299
  <p class="capsulas-section-description">Confira exemplos práticos de implementação do padrão.</p>
297
300
  </div>
298
301
 
@@ -343,7 +346,7 @@
343
346
  </div>
344
347
 
345
348
  <div>
346
- <h2 class="capsulas-section-title-caps">O que não fazer?</h2>
349
+ <h2 class="capsulas-section-title-caps-dark">O que não fazer?</h2>
347
350
  {{ page.o_que_nao_fazer_resumo|safe }}
348
351
 
349
352
  {% if page.o_que_nao_fazer_detalhado %}
@@ -381,7 +384,7 @@
381
384
  <section id="section-norms" class="capsulas-content-section">
382
385
  <div class="capsulas-container">
383
386
  <div class="capsulas-section-header">
384
- <h2 class="capsulas-section-title-caps">Normas de referência</h2>
387
+ <h2 class="capsulas-section-title-caps-dark">Normas de referência</h2>
385
388
  <p class="capsulas-section-description">Conheça as principais normas e diretrizes relacionadas.</p>
386
389
  </div>
387
390
 
@@ -399,10 +402,10 @@
399
402
 
400
403
  <!-- Cápsulas Relacionadas -->
401
404
  {% if capsulas_relacionadas %}
402
- <section class="capsulas-content-section" style="background-color: var(--primary-light);">
405
+ <section class="capsulas-hero" role="region" aria-labelledby="hero-title" style="background-color: var(--primary-light);">
403
406
  <div class="capsulas-container">
404
407
  <div class="capsulas-section-header">
405
- <h2 class="capsulas-section-title-caps">Cápsulas Relacionadas</h2>
408
+ <h2 class="capsulas-section-title-caps-dark">Cápsulas Relacionadas</h2>
406
409
  <p class="capsulas-section-description">Explore outras cápsulas que podem complementar seu aprendizado.</p>
407
410
  </div>
408
411
 
@@ -445,33 +448,127 @@
445
448
  const tabsScroll = document.getElementById('tabs-scroll');
446
449
  const prevBtn = document.getElementById('prev-tab');
447
450
  const nextBtn = document.getElementById('next-tab');
448
-
451
+
449
452
  // Scroll Navigation
450
453
  if (prevBtn && nextBtn && tabsScroll) {
451
454
  prevBtn.addEventListener('click', () => {
452
455
  tabsScroll.scrollBy({ left: -200, behavior: 'smooth' });
456
+ // Foco no primeiro item visível após scrollar para a esquerda
457
+ const visibleTabs = Array.from(tabs).filter(t => {
458
+ const rect = t.getBoundingClientRect();
459
+ return rect.left >= tabsScroll.getBoundingClientRect().left;
460
+ });
461
+ if (visibleTabs.length > 0) visibleTabs[0].focus();
453
462
  });
454
-
463
+
455
464
  nextBtn.addEventListener('click', () => {
456
465
  tabsScroll.scrollBy({ left: 200, behavior: 'smooth' });
466
+ // Foco no último item visível após scrollar para a direita
467
+ setTimeout(() => {
468
+ const visibleTabs = Array.from(tabs).filter(t => {
469
+ const rect = t.getBoundingClientRect();
470
+ return rect.right <= tabsScroll.getBoundingClientRect().right;
471
+ });
472
+ if (visibleTabs.length > 0) visibleTabs[visibleTabs.length - 1].focus();
473
+ }, 300);
457
474
  });
458
475
  }
459
-
460
- // Tab Click
461
- tabs.forEach(tab => {
476
+
477
+ // Tab Click - Com suporte a navegação por teclado
478
+ tabs.forEach((tab, idx) => {
479
+ // Configuração inicial de ARIA para cada tab
480
+ const targetId = tab.getAttribute('data-target');
481
+ tab.setAttribute('role', 'tab');
482
+ tab.setAttribute('aria-controls', targetId);
483
+
484
+ // Definir aria-selected no carregamento
485
+ if (tab.classList.contains('capsulas-tab-item--active')) {
486
+ tab.setAttribute('aria-selected', 'true');
487
+ tab.setAttribute('tabindex', '0');
488
+ } else {
489
+ tab.setAttribute('aria-selected', 'false');
490
+ tab.setAttribute('tabindex', '-1');
491
+ }
492
+
493
+ // Configurar correspondente section como tabpanel
494
+ const targetSection = document.getElementById(targetId);
495
+ if (targetSection) {
496
+ targetSection.setAttribute('role', 'tabpanel');
497
+ targetSection.setAttribute('aria-labelledby', tab.id || `tab-${idx}`);
498
+ if (!tab.id) tab.id = `tab-${idx}`;
499
+
500
+ // Ocultar tabpanels inativos de leitores de tela se necessário
501
+ if (!tab.classList.contains('capsulas-tab-item--active')) {
502
+ targetSection.setAttribute('tabindex', '0'); // Permite foco quando não visível
503
+ }
504
+ }
505
+
462
506
  tab.addEventListener('click', () => {
463
- const targetId = tab.getAttribute('data-target');
464
- const targetSection = document.getElementById(targetId);
507
+ activateTab(tab);
508
+ });
509
+
510
+ // Suporte a navegação por teclado
511
+ tab.addEventListener('keydown', (e) => {
512
+ // Ativar com Enter ou Space
513
+ if (e.key === 'Enter' || e.key === ' ') {
514
+ e.preventDefault();
515
+ activateTab(tab);
516
+ }
465
517
 
466
- tabs.forEach(t => t.classList.remove('capsulas-tab-item--active'));
467
- tab.classList.add('capsulas-tab-item--active');
518
+ // Navegação com setas
519
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
520
+ e.preventDefault();
521
+
522
+ const tabsList = Array.from(tabs);
523
+ const currentIdx = tabsList.indexOf(tab);
524
+ let nextTab;
525
+
526
+ if (e.key === 'ArrowLeft') {
527
+ nextTab = tabsList[currentIdx - 1] || tabsList[tabsList.length - 1];
528
+ } else {
529
+ nextTab = tabsList[currentIdx + 1] || tabsList[0];
530
+ }
531
+
532
+ // Mover foco (sem ativar)
533
+ nextTab.focus();
534
+ }
468
535
 
469
- if (targetSection) {
470
- targetSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
536
+ // Home e End para navegar ao primeiro/último tab
537
+ if (e.key === 'Home') {
538
+ e.preventDefault();
539
+ tabs[0].focus();
540
+ }
541
+ if (e.key === 'End') {
542
+ e.preventDefault();
543
+ tabs[tabs.length - 1].focus();
471
544
  }
472
545
  });
473
546
  });
474
-
547
+
548
+ // Função para ativar uma tab e seu conteúdo
549
+ function activateTab(selectedTab) {
550
+ const targetId = selectedTab.getAttribute('data-target');
551
+ const targetSection = document.getElementById(targetId);
552
+
553
+ // Atualizar estados ARIA e classes para todas as tabs
554
+ tabs.forEach(t => {
555
+ const isSelected = t === selectedTab;
556
+ t.classList.toggle('capsulas-tab-item--active', isSelected);
557
+ t.setAttribute('aria-selected', isSelected ? 'true' : 'false');
558
+ t.setAttribute('tabindex', isSelected ? '0' : '-1');
559
+ });
560
+
561
+ if (targetSection) {
562
+ // Rolar para a seção - usar uma suavização mais acessível
563
+ targetSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
564
+
565
+ // Anunciar para tecnologias assistivas que o conteúdo mudou
566
+ // Opcionalmente, pode-se focar no painel para leitores de tela
567
+ targetSection.setAttribute('tabindex', '-1');
568
+ targetSection.focus({ preventScroll: true }); // Evita saltos duplos
569
+ }
570
+ }
571
+
475
572
  // Sticky Tab Navigation
476
573
  if (tabNavigation) {
477
574
  let lastScroll = 0;
@@ -484,43 +581,109 @@
484
581
 
485
582
  if (currentScroll > heroHeight - 100) {
486
583
  tabNavigation.classList.add('fixed');
584
+ // Adicionar atributo ARIA para indicar que é fixo
585
+ tabNavigation.setAttribute('aria-sticky', 'true');
487
586
  } else {
488
587
  tabNavigation.classList.remove('fixed');
588
+ tabNavigation.setAttribute('aria-sticky', 'false');
489
589
  }
490
-
491
- // Update active tab based on scroll position
590
+
591
+ // Update active tab based on scroll position - com ARIA
492
592
  sections.forEach((section, index) => {
493
593
  const sectionTop = section.offsetTop - 200;
494
594
  const sectionBottom = sectionTop + section.offsetHeight;
495
595
 
496
596
  if (currentScroll >= sectionTop && currentScroll < sectionBottom && tabs[index]) {
497
- tabs.forEach(t => t.classList.remove('capsulas-tab-item--active'));
498
- tabs[index].classList.add('capsulas-tab-item--active');
597
+ tabs.forEach(t => {
598
+ const isActive = t === tabs[index];
599
+ t.classList.toggle('capsulas-tab-item--active', isActive);
600
+ t.setAttribute('aria-selected', isActive ? 'true' : 'false');
601
+ t.setAttribute('tabindex', isActive ? '0' : '-1');
602
+ });
499
603
  }
500
604
  });
501
-
605
+
502
606
  lastScroll = currentScroll;
503
607
  });
504
608
  }
505
609
  });
506
-
507
- // Accordion Toggle
610
+
611
+ // Accordion Toggle - Melhorado com suporte ARIA
508
612
  function toggleAccordion(id) {
509
613
  const accordion = document.getElementById(id);
510
614
  if (accordion) {
511
- accordion.classList.toggle('active');
615
+ const isActive = accordion.classList.toggle('active');
616
+
617
+ // Atualize o estado ARIA para todos os controladores relacionados
618
+ const accordionHeader = accordion.querySelector('.capsulas-accordion__header');
619
+ const accordionBtns = document.querySelectorAll(`[aria-controls="${id}"]`);
620
+
621
+ // Atualize estado expandido em elementos relacionados
622
+ if (accordionHeader) {
623
+ accordionHeader.setAttribute('aria-expanded', isActive);
624
+ }
625
+
626
+ accordionBtns.forEach(btn => {
627
+ btn.setAttribute('aria-expanded', isActive);
628
+ });
629
+
630
+ // Ajuste o foco, especialmente útil para tecnologias assistivas
631
+ if (isActive) {
632
+ // Encontrar o primeiro elemento focável dentro do accordion
633
+ const firstFocusable = accordion.querySelector('a[href], button, input, textarea, select, [tabindex]:not([tabindex="-1"])');
634
+ if (firstFocusable) {
635
+ // Dar um tempo para a animação abrir e depois focar
636
+ setTimeout(() => firstFocusable.focus(), 100);
637
+ } else if (accordion.querySelector('.capsulas-accordion__body')) {
638
+ // Se não houver elemento focável, pelo menos dê foco ao corpo
639
+ const body = accordion.querySelector('.capsulas-accordion__body');
640
+ body.setAttribute('tabindex', '-1');
641
+ setTimeout(() => body.focus(), 100);
642
+ }
643
+ }
512
644
  }
513
645
  }
514
-
515
- // Smooth scroll for hero CTA
646
+
647
+ // Keyboard support for accordions
516
648
  document.addEventListener("DOMContentLoaded", function() {
649
+ // Adicionar suporte de teclado para headers do accordion
650
+ const accordionHeaders = document.querySelectorAll('.capsulas-accordion__header');
651
+ accordionHeaders.forEach(header => {
652
+ header.addEventListener('keydown', (e) => {
653
+ // Ativar com Enter ou Space
654
+ if (e.key === 'Enter' || e.key === ' ') {
655
+ e.preventDefault();
656
+ const accordionId = header.getAttribute('aria-controls');
657
+ if (accordionId) {
658
+ toggleAccordion(accordionId);
659
+ }
660
+ }
661
+ });
662
+ });
663
+
664
+ // Smooth scroll for hero CTA - Melhorado com anúncio para leitores de tela
517
665
  const heroCta = document.querySelector('.capsulas-hero__cta');
518
666
  if (heroCta) {
519
667
  heroCta.addEventListener('click', (e) => {
520
668
  e.preventDefault();
521
669
  const contentElement = document.getElementById('content');
522
670
  if (contentElement) {
523
- contentElement.scrollIntoView({ behavior: 'smooth' });
671
+ contentElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
672
+
673
+ // Melhorar a acessibilidade focando no conteúdo após rolagem
674
+ contentElement.setAttribute('tabindex', '-1');
675
+ contentElement.focus({ preventScroll: true });
676
+
677
+ // Opcionalmente, anunciar para leitores de tela
678
+ const announcer = document.createElement('div');
679
+ announcer.setAttribute('aria-live', 'polite');
680
+ announcer.classList.add('sr-only'); // Adicione esta classe no seu CSS
681
+ announcer.textContent = "Conteúdo principal carregado";
682
+ document.body.appendChild(announcer);
683
+
684
+ setTimeout(() => {
685
+ document.body.removeChild(announcer);
686
+ }, 1000);
524
687
  }
525
688
  });
526
689
  }
@@ -1429,14 +1429,14 @@ def clean_html(text):
1429
1429
  def get_default_description(page):
1430
1430
  """Descrição padrão baseada no tipo"""
1431
1431
  defaults = {
1432
- 'HomePage': 'Portal da ENAP - Escola Nacional de Administração Pública',
1432
+ 'HomePage': 'Portal da Enap - Escola Nacional de Administração Pública.',
1433
1433
  'BlogPage': f'Artigo sobre {page.title} no blog da ENAP',
1434
1434
  'EventPage': f'Evento: {page.title} - ENAP',
1435
1435
  'CoursePage': f'Curso {page.title} oferecido pela ENAP',
1436
1436
  }
1437
1437
 
1438
1438
  page_type = page.__class__.__name__
1439
- return defaults.get(page_type, f'{page.title} - ENAP - Escola Nacional de Administração Pública')
1439
+ return defaults.get(page_type, f'{page.title} - Enap - Escola Nacional de Administração Pública.')
1440
1440
 
1441
1441
 
1442
1442
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wagtail-enap-designsystem
3
- Version: 1.2.1.192
3
+ Version: 1.2.1.194
4
4
  Summary: Módulo de componentes utilizado nos portais ENAP, desenvolvido com Wagtail + CodeRedCMS
5
5
  Author: Renan Campos
6
6
  Author-email: renan.oliveira@enap.gov.br