|
130 | 130 | margin-top: 10px; |
131 | 131 | } |
132 | 132 |
|
| 133 | + /* FAQ ACCORDION W TREŚCI NEWSA */ |
| 134 | + .faq-accordion { |
| 135 | + margin: 20px 0 35px 0; |
| 136 | + border: 1px solid var(--border); |
| 137 | + border-radius: 10px; |
| 138 | + background: rgba(255, 255, 255, 0.02); |
| 139 | + overflow: hidden; |
| 140 | + } |
| 141 | + .faq-accordion-intro { |
| 142 | + padding: 18px 20px 4px 20px; |
| 143 | + } |
| 144 | + .faq-item { |
| 145 | + border-top: 1px solid var(--border); |
| 146 | + } |
| 147 | + .faq-item:first-of-type { |
| 148 | + border-top: 0; |
| 149 | + } |
| 150 | + .faq-question { |
| 151 | + list-style: none; |
| 152 | + cursor: pointer; |
| 153 | + padding: 16px 20px; |
| 154 | + font-family: 'JetBrains Mono', monospace; |
| 155 | + font-weight: 700; |
| 156 | + color: #fff; |
| 157 | + display: flex; |
| 158 | + align-items: center; |
| 159 | + justify-content: space-between; |
| 160 | + gap: 15px; |
| 161 | + transition: background 0.2s ease, color 0.2s ease; |
| 162 | + outline: none; |
| 163 | + } |
| 164 | + .faq-question::-webkit-details-marker { |
| 165 | + display: none; |
| 166 | + } |
| 167 | + .faq-question::after { |
| 168 | + content: '⌄'; |
| 169 | + font-size: 1.05rem; |
| 170 | + color: var(--accent-blue); |
| 171 | + transition: transform 0.2s ease; |
| 172 | + flex-shrink: 0; |
| 173 | + } |
| 174 | + .faq-item[open] .faq-question::after { |
| 175 | + transform: rotate(180deg); |
| 176 | + } |
| 177 | + .faq-question:hover { |
| 178 | + background: rgba(0, 210, 255, 0.08); |
| 179 | + color: var(--accent-blue); |
| 180 | + } |
| 181 | + .faq-question:focus-visible { |
| 182 | + box-shadow: inset 0 0 0 2px var(--accent-blue); |
| 183 | + border-radius: 4px; |
| 184 | + } |
| 185 | + .faq-answer { |
| 186 | + max-height: 0; |
| 187 | + overflow: hidden; |
| 188 | + opacity: 0; |
| 189 | + transition: max-height 0.28s ease, opacity 0.2s ease; |
| 190 | + padding: 0 20px; |
| 191 | + } |
| 192 | + .faq-item[open] .faq-answer { |
| 193 | + max-height: 1200px; |
| 194 | + opacity: 1; |
| 195 | + padding: 0 20px 18px 20px; |
| 196 | + } |
| 197 | + .faq-answer > *:last-child { |
| 198 | + margin-bottom: 0; |
| 199 | + } |
| 200 | + |
133 | 201 | /* SPIS TREŚCI (TOC) W BOCZNYM PANELU */ |
134 | 202 | .sidebar-toc { |
135 | 203 | position: sticky; |
|
287 | 355 | .post-container { grid-template-columns: 1fr; padding: 0 20px; } |
288 | 356 | .sidebar-toc { position: static; } |
289 | 357 | .back-to-news-floating { bottom: 20px; right: 20px; padding: 10px 14px; font-size: 0.75rem; } |
| 358 | + .faq-question { padding: 14px 16px; font-size: 0.9rem; } |
| 359 | + .faq-item[open] .faq-answer { padding: 0 16px 16px 16px; } |
| 360 | + .faq-answer { padding: 0 16px; } |
290 | 361 | } |
291 | 362 | </style> |
292 | 363 |
|
@@ -340,10 +411,89 @@ <h4 class="toc-title">// Spis Treści</h4> |
340 | 411 | </a> |
341 | 412 |
|
342 | 413 | <script> |
| 414 | + // FAQ markdown structure expected in the post body: |
| 415 | + // - `## FAQ` / `## Najczęściej zadawane pytania` (or heading containing these phrases) starts FAQ section |
| 416 | + // - each `###` in this section is treated as one question |
| 417 | + // - all elements under that `###` until next `###` or next `##` are treated as answer content |
| 418 | + function normalizeHeadingText(text) { |
| 419 | + return (text || '') |
| 420 | + .toLowerCase() |
| 421 | + .normalize('NFD') |
| 422 | + .replace(/[\u0300-\u036f]/g, '') |
| 423 | + .trim(); |
| 424 | + } |
| 425 | + |
| 426 | + function isFaqSectionHeading(text) { |
| 427 | + const normalized = normalizeHeadingText(text); |
| 428 | + return normalized.includes('faq') || normalized.includes('najczesciej zadawane pytania'); |
| 429 | + } |
| 430 | + |
| 431 | + function transformFaqToAccordion(articleBody) { |
| 432 | + const headings = Array.from(articleBody.querySelectorAll('h2')); |
| 433 | + const faqHeading = headings.find((heading) => isFaqSectionHeading(heading.textContent)); |
| 434 | + if (!faqHeading) return; |
| 435 | + |
| 436 | + const sectionNodes = []; |
| 437 | + let cursor = faqHeading.nextElementSibling; |
| 438 | + while (cursor) { |
| 439 | + if (cursor.tagName === 'H1' || cursor.tagName === 'H2') break; |
| 440 | + sectionNodes.push(cursor); |
| 441 | + cursor = cursor.nextElementSibling; |
| 442 | + } |
| 443 | + |
| 444 | + if (sectionNodes.length === 0) return; |
| 445 | + if (!sectionNodes.some((node) => node.tagName === 'H3')) return; |
| 446 | + |
| 447 | + const faqWrapper = document.createElement('section'); |
| 448 | + faqWrapper.className = 'faq-accordion'; |
| 449 | + faqWrapper.setAttribute('aria-label', 'Najczęściej zadawane pytania'); |
| 450 | + |
| 451 | + const faqIntro = document.createElement('div'); |
| 452 | + faqIntro.className = 'faq-accordion-intro'; |
| 453 | + |
| 454 | + let currentAnswer = null; |
| 455 | + let hasQuestions = false; |
| 456 | + |
| 457 | + sectionNodes.forEach((node) => { |
| 458 | + if (node.tagName === 'H3') { |
| 459 | + const details = document.createElement('details'); |
| 460 | + details.className = 'faq-item'; |
| 461 | + |
| 462 | + const summary = document.createElement('summary'); |
| 463 | + summary.className = 'faq-question'; |
| 464 | + summary.textContent = node.textContent.trim(); |
| 465 | + details.appendChild(summary); |
| 466 | + |
| 467 | + currentAnswer = document.createElement('div'); |
| 468 | + currentAnswer.className = 'faq-answer'; |
| 469 | + details.appendChild(currentAnswer); |
| 470 | + |
| 471 | + faqWrapper.appendChild(details); |
| 472 | + node.remove(); |
| 473 | + hasQuestions = true; |
| 474 | + return; |
| 475 | + } |
| 476 | + |
| 477 | + if (currentAnswer) { |
| 478 | + currentAnswer.appendChild(node); |
| 479 | + } else { |
| 480 | + faqIntro.appendChild(node); |
| 481 | + } |
| 482 | + }); |
| 483 | + |
| 484 | + if (!hasQuestions) return; |
| 485 | + if (faqIntro.childNodes.length > 0) faqWrapper.prepend(faqIntro); |
| 486 | + faqHeading.insertAdjacentElement('afterend', faqWrapper); |
| 487 | + } |
| 488 | + |
343 | 489 | // AUTOMATYCZNY SPIS TREŚCI ZE STRUKTURY NAGŁÓWKÓW |
344 | 490 | const articleBody = document.getElementById('articleBody'); |
345 | 491 | const tocList = document.getElementById('tocList'); |
346 | | - const headings = articleBody.querySelectorAll('h2, h3'); |
| 492 | + transformFaqToAccordion(articleBody); |
| 493 | + |
| 494 | + const headings = Array.from(articleBody.querySelectorAll('h2, h3')).filter( |
| 495 | + (heading) => !heading.closest('.faq-accordion') |
| 496 | + ); |
347 | 497 |
|
348 | 498 | if(headings.length === 0) { |
349 | 499 | tocList.innerHTML = '<li style="color: var(--text-muted)">// Brak nagłówków</li>'; |
|
0 commit comments