すべてのパネルが開いている場合、一括操作ですべて閉じます。それ以外の場合は、すべて開きます。ハンドラーは、状態を変更する必要があるネイティブボタンのみを有効にします。hidden や aria-expanded を直接変更しないため、ネイティブイベントとそこから算出する件数の整合性が保たれます。次の操作が伝わるよう、コントロールのラベルは Open all sections と Close all sections の間で切り替わります。
Europa Component Library デザインシステム Europa のキーボード操作と段階的な読み進め方
<!doctype html><html lang="en" class="no-js"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Public conversation brief</title><link rel="stylesheet" href="./node_modules/@ecl/preset-ec/dist/styles/ecl-ec.css"><link rel="stylesheet" href="./ecl.css"></head><body><main><header class="mast"><p class="eyebrow">European Commission preset / original study</p><h1>A clear brief for a public conversation</h1><p>Explore three preparation notes with native ECL expandable sections and an explicit open-all control.</p></header><p class="scope">ECL EC 4.11.2 CSS and native Accordion runtime. Original OpenDesign sample text; this is not an EU service, funding programme or legal guide.</p><div class="toolbar"><p id="count" role="status">0 of 3 sections open</p><button id="all" type="button" class="ecl-button ecl-button--secondary">Open all sections</button></div><div class="ecl-accordion" data-ecl-accordion data-ecl-auto-init="Accordion"><section class="ecl-accordion__item"><h2 class="ecl-accordion__title"><button class="ecl-accordion__toggle" data-ecl-accordion-toggle aria-controls="purpose" aria-expanded="true" id="toggle-purpose" type="button"><span class="ecl-accordion__toggle-flex"><span class="ecl-accordion__toggle-title">Define the purpose before collecting information</span><span class="ecl-accordion__toggle-indicator"><svg class="ecl-accordion__toggle-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M11 3h2v8h8v2h-8v8h-2v-8H3v-2h8z"/></svg><svg class="ecl-accordion__toggle-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M3 11h18v2H3z"/></svg></span></span></button></h2><div class="ecl-accordion__content" id="purpose" role="region" aria-labelledby="toggle-purpose"><p>This fictional planning note describes a small community consultation. It is sample editorial content, not an EU funding call, legal requirement or official application process.</p><h3>Make a decision possible</h3><ol><li>State which decision the conversation will inform.</li><li>List information already available before asking participants for more.</li><li>Name what remains outside the consultation.</li></ol><aside class="decision"><h3>Keep the outcome proportionate</h3><p>A short conversation may support a next step; it does not by itself prove consent, eligibility or public support.</p></aside></div></section><section class="ecl-accordion__item"><h2 class="ecl-accordion__title"><button class="ecl-accordion__toggle" data-ecl-accordion-toggle aria-controls="participation" aria-expanded="true" id="toggle-participation" type="button"><span class="ecl-accordion__toggle-flex"><span class="ecl-accordion__toggle-title">Make participation understandable and accessible</span><span class="ecl-accordion__toggle-indicator"><svg class="ecl-accordion__toggle-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M11 3h2v8h8v2h-8v8h-2v-8H3v-2h8z"/></svg><svg class="ecl-accordion__toggle-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M3 11h18v2H3z"/></svg></span></span></button></h2><div class="ecl-accordion__content" id="participation" role="region" aria-labelledby="toggle-participation"><p>Give participants enough context to decide whether and how to take part. The invitation should explain the topic, expected duration, available formats and the use of any notes.</p><h3>Provide usable alternatives</h3><ol><li>Offer a plain-language explanation of the activity.</li><li>Allow a person to contribute without speaking to the whole group.</li><li>Explain how to ask for an accessible format.</li></ol><aside class="decision"><h3>Check the invitation itself</h3><p>A technically accessible page is only one part of participation. Timing, language and the route for asking a question also affect who can join.</p></aside></div></section><section class="ecl-accordion__item"><h2 class="ecl-accordion__title"><button class="ecl-accordion__toggle" data-ecl-accordion-toggle aria-controls="record" aria-expanded="true" id="toggle-record" type="button"><span class="ecl-accordion__toggle-flex"><span class="ecl-accordion__toggle-title">Record decisions and unresolved questions separately</span><span class="ecl-accordion__toggle-indicator"><svg class="ecl-accordion__toggle-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M11 3h2v8h8v2h-8v8h-2v-8H3v-2h8z"/></svg><svg class="ecl-accordion__toggle-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M3 11h18v2H3z"/></svg></span></span></button></h2><div class="ecl-accordion__content" id="record" role="region" aria-labelledby="toggle-record"><p>After the session, distinguish what was agreed from what still needs investigation. A clean record helps the next reader understand how a proposal changed and why.</p><h3>Prepare a readable follow-up</h3><ol><li>Write the next action with an owner and review date.</li><li>Make open questions visible alongside conclusions.</li><li>Invite participants to correct an inaccurate summary.</li></ol><aside class="decision"><h3>Avoid a false completion signal</h3><p>Closing these panels is a reading action only. This preview sends no consultation response and records no formal approval.</p></aside></div></section></div><p class="footer">Each heading is a native button. Use Tab to move between headings and Enter or Space to toggle; several sections can remain open. Without JavaScript the notes remain readable.</p></main><script src="./node_modules/@ecl/preset-ec/dist/scripts/ecl-ec.js"></script><script src="./ecl-app.js"></script></body></html>
HTML ファイルを index.html として保存し、ほかの付属ファイルの名前は変更しないでください。
ecl-app.js — 完全なソース
ネイティブの初期化と、イベント駆動型の一括操作を実装しています。初期状態では HTML を読めます。
JavaScript
document.documentElement.classList.remove('no-js');ECL.autoInit();const root=document.querySelector('[data-ecl-accordion]');const buttons=[...root.querySelectorAll('[data-ecl-accordion-toggle]')];const all=document.querySelector('#all');function sync(){let open=buttons.filter(b=>b.getAttribute('aria-expanded')==='true').length;document.querySelector('#count').textContent=open+' of '+buttons.length+' sections open';all.textContent=open===buttons.length?'Close all sections':'Open all sections';}root.ECLAccordion.on('onToggle',sync);buttons.forEach(b=>b.click());all.addEventListener('click',()=>{let close=buttons.every(b=>b.getAttribute('aria-expanded')==='true');buttons.filter(b=>(b.getAttribute('aria-expanded')==='true')===close).forEach(b=>b.click());});sync();