#main-content > p{margin: 0;} #main-content :is(.news-cbl, .interviews-cbl){display: none;} /* reference wrapper */ .section .reference-wrapper > *{margin-bottom: 12px;} /* sort component */ .section .sort-wrapper{display: flex; align-items: center; gap: 12px; margin-bottom: 24px; margin-left: auto; width: fit-content;} .section .sort-wrapper p{margin: 0;} .section .sort-wrapper .sort-select{border: 1px solid #B7C2CF; border-radius: 6px; padding: 16px; cursor: pointer; position: relative;} .section .sort-wrapper .sort-select:hover:not(:has(.options-wrapper:hover)) {text-decoration: underline; background: rgb(240, 240, 240);} .section .sort-wrapper .sort-select:focus-visible{outline: 2px dashed black;} .section .sort-wrapper .sort-select .selected-sort{display: flex; align-items: center; gap: 6px;} .section .sort-wrapper .sort-select .options-wrapper{display: none; position: absolute; top: 105%; background: white;z-index: 1;margin-left: -16px; width: 100%;border-radius: 6px; border: 1px solid #E3E6EB;} .section .sort-wrapper .sort-select[aria-expanded="true"] .selected-sort > img{transform: rotate(180deg);} .section .sort-wrapper .sort-select[aria-expanded="true"] .options-wrapper{display: block;} .section .sort-wrapper .sort-select .options-wrapper > [role="option"]{padding: 16px;} .section .sort-wrapper .sort-select .options-wrapper > [role="option"]:not(:last-child){border-bottom: 1px solid #E3E6EB;} .section .sort-wrapper .sort-select .options-wrapper > [aria-selected="true"]{font-weight: 600;} .section .sort-wrapper .sort-select .options-wrapper > [aria-selected="false"]:hover{text-decoration: underline; background: rgb(240, 240, 240);} /* */ /* load more button */ #news-section .load-more, #interviews-section .load-more{margin-top: 40px; margin-inline: auto; display: none; width: fit-content;} /* */ /* intro section */ #intro-section{position: relative; z-index: 1;} #intro-section .back-img{position: absolute; right: min(-500px, -37%); z-index: 0;} #intro-section .container{position: relative; z-index: 1;} /* news section */ #news-section{padding-bottom: 84px; position: relative; z-index: 2;} #news-section .container{position: relative; z-index: 2;} #news-section .articles-wrapper .news-grid{display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px;} #news-section .articles-wrapper .news-grid .news-item{grid-column: span 2; overflow: hidden; border-radius: 12px; box-shadow: 0px 2px 12px 0px rgba(0, 24, 50, 0.08); display: flex; flex-direction: column; gap: 24px; background: white;} #news-section .articles-wrapper .news-grid .news-item .article-details{padding-inline: 40px; padding-bottom: 40px; display: flex; flex-direction: column; flex: 1;} #news-section .articles-wrapper .news-grid .news-item .article-preview{width: 100%; height: 200px; object-fit: cover; clip-path: ellipse(70% 142% at 71% -46%);} #news-section .articles-wrapper .news-grid .news-item .article-title{font-size: 20px; font-style: normal; font-weight: 400; line-height: 24px;} #news-section .articles-wrapper .news-grid .news-item .article-date{font-size: 14px; font-style: normal; font-weight: 400; line-height: 20px; display: flex; align-items: center; gap: 8px;} #news-section .articles-wrapper .news-grid .news-item .article-link{margin-left: auto; margin-top: auto;} #news-section .articles-wrapper .news-grid .news-item:is(:nth-child(8n+1), :nth-child(8n+2)) {grid-column: span 3; } #news-section .articles-wrapper .news-grid .news-item:is(:nth-child(8n+1), :nth-child(8n+2)) .article-preview{clip-path: ellipse(55% 146% at 59% -46%);} .back-2-container{position: relative;} .back-2-container .back-img{position: absolute; top: -600px; left: -7%;} /* interviews section */ #interviews-section{position: relative; z-index: 3;} #interviews-section .interviews-grid{display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px;} #interviews-section .interview-item{display: flex; flex-direction: column; border-radius: 12px; box-shadow: 0px 2px 12px 0px rgba(0, 24, 50, 0.08); overflow: hidden; background: white;} #interviews-section .interview-item > .interview-preview{width: 100%; height: 200px; clip-path: ellipse(63% 92% at 66% -4%); object-fit: cover;} #interviews-section .interview-item > .interview-details{padding: 24px 16px 40px 16px; display: flex; flex-direction: column; flex: 1;} #interviews-section .interview-item > .interview-details > .interview-country{font-size: 20px; font-style: normal; font-weight: 400; line-height: 24px; border-bottom: 1px solid #E3E6EB; padding-bottom: 12px; margin-bottom: 12px;} #interviews-section .interview-item > .interview-details > .interview-name{display: flex; gap: 8px; margin-bottom: 12px; font-weight: 600;} #interviews-section .interview-item > .interview-details > .interview-name > img{height: fit-content;} #interviews-section .interview-item > .interview-details > .interview-prof{font-size: 14px; padding-left: 32px;} #interviews-section .interview-item > .interview-details > .interview-link{margin-left: auto; margin-top: auto;} @media screen and (max-width: 1000px){ #news-section .articles-wrapper .news-grid{grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));} #news-section .articles-wrapper .news-grid .news-item{grid-column: span 1 !important;} #news-section .articles-wrapper .news-grid .news-item .article-preview{clip-path: ellipse(80% 142% at 71% -46%) !important;} } @media screen and (max-width: 768px){ .section .reference-wrapper > :last-child{margin-bottom: 24px;} } |
<section class="section" id="intro-section"> <img class="back-img" src="/digital-building-blocks/sites/download/attachments/760938508/vec-background-1.svg" alt="" aria-hidden="true"> <div class="container"> <div class="cols"> <div class="col-8"> <h1><span class="heading-subtitle">News & Interviews</span>Updates & Insights</h1> <p class="lead w-75 is-desktop">Stay informed with the latest news, technical updates, and success stories on the development of the Once-Only Technical System infrastructure by EU Member States and the European Commission. Discover insightful interviews with EU Member States about its implementation.</p> </div> </div> </div> </section> |
<section class="section" id="news-section"> <div class="container"> <div class="cols"> <div class="col-12 articles-wrapper"> <div class="reference-wrapper"> <h2>News</h2> <p class="lead w75 is-desktop">Browse all articles</p> </div> <div class="sort-wrapper"> <div class="left-col"> <p>Sort by:</p> </div> <div class="right-col"> <div class="sort-select" role="button" aria-expanded="false" tabindex="0"> <p class="selected-sort"> <span>Date new to old</span> <img src="/digital-building-blocks/sites/download/attachments/760938508/ico-chevron-down.svg" alt=""> </p> <div class="options-wrapper" role="listbox"> <p role="option" tabindex="0" aria-selected="true" value="desc">Date new to old</p> <p role="option" tabindex="0" aria-selected="false" value="asc">Date old to new</p> </div> </div> </div> </div> <div class="news-grid"></div> <a class="btn ghost load-more" href="javascript:void(0)" aria-label="Load more articles"><span>Load more articles</span></a> </div> </div> </div> </section> |
<div class="back-2-container"> <img class="back-img" src="/digital-building-blocks/sites/download/attachments/760938508/vec-background-2.svg" alt="" aria-hidden="true"> </div> |
<section class="section" id="interviews-section"> <div class="container"> <div class="cols"> <div class="col-12 interviews-wrapper"> <div class="reference-wrapper"> <h2>Interviews</h2> <p class="lead w75 is-desktop">Browse all interviews</p> </div> <div class="sort-wrapper"> <div class="left-col"> <p>Sort by:</p> </div> <div class="right-col"> <div class="sort-select" role="button" aria-expanded="false" tabindex="0"> <p class="selected-sort"> <span>Date new to old</span> <img src="/digital-building-blocks/sites/download/attachments/760938508/ico-chevron-down.svg" alt=""> </p> <div class="options-wrapper" role="listbox"> <p role="option" tabindex="0" aria-selected="true" value="desc">Date new to old</p> <p role="option" tabindex="0" aria-selected="false" value="asc">Date old to new</p> </div> </div> </div> </div> <div class="interviews-grid"></div> <a class="btn ghost load-more" href="javascript:void(0)" aria-label="Load more interviews"><span>Load more interviews</span></a> </div> </div> </div> </section> |
<script> document.addEventListener('DOMContentLoaded', ev => { newsContent(); interviewsContent(); window.addEventListener('click', ev => { if(!ev.target.closest('.sort-select')){ document.querySelectorAll('.sort-select').forEach(select => { select.setAttribute('aria-expanded', false); }); } }); function newsContent(){ const items = []; const loadMoreBtn = document.querySelector('.articles-wrapper .load-more'); let itemsDisplayed = 0; let newsList = document.querySelector('.section .news-grid'); const contentByLabel = document.querySelector('.news-cbl .content-by-label'); populateArray(); if(items.length > 5){ loadMoreBtn.style.display = 'flex'; } // descending order by date sortFun('desc'); setupSorting(); addDomElements(false); loadMoreBtn.addEventListener('click', ev => { ev.preventDefault(); addDomElements(false); }); contentByLabel.remove(); // functions function populateArray(){ Array.from(contentByLabel.children).forEach(element => { try{ const arTitle = element.querySelector('.details > a').innerText; const arLink = `https://ec.europa.eu${element.querySelector('.details > a').getAttribute('href')}`; const arTime = formatTime(element.querySelector('.details time').getAttribute('datetime')); const sortableTime = new Date(element.querySelector('.details time').getAttribute('datetime')); const arPreview = element.querySelector('.details .exc-preview').innerText; const domElement = document.createElement('div'); domElement.classList.add('news-item'); domElement.innerHTML = ` <img loading="lazy" class="article-preview" src="${arPreview}" alt="" aria-hidden="true"> <div class="article-details"> <h3 class="article-title">${arTitle}</h3> <p class="article-date"><img alt="Publication date" src="/digital-building-blocks/sites/download/attachments/760938508/ico-date.svg"/> ${arTime}</p> <a class="article-link link-cta primary after" href="${arLink}"><span>Read article</span></a> </div> `; items.push({ arTitle: arTitle, arLink: arLink, arTime: arTime, sortableTime: sortableTime, arPreview: arPreview, arDOMElement: domElement }); }catch(err){} }); } function addDomElements(flag){ // if flag = true, it will render elements from 0 to whatever value the itemsDisplayed was // (if you have clicked the load more button before - pretty much if you have clicked on sort). If false it will // start from the last itemsDisplayed value let num = 5; if(flag){ num = itemsDisplayed; } for (let index = 0; index < num; index++) { let element; flag ? element = items[index] : element = items[itemsDisplayed]; if(!element){ loadMoreBtn.style.display = 'none'; break; } newsList.appendChild(element.arDOMElement); !flag ? itemsDisplayed++ : null; } const rowIndexing = itemsDisplayed % 8; if(rowIndexing !== 0 && rowIndexing !== 2 && rowIndexing !== 5){ let element = items[itemsDisplayed]; itemsDisplayed++; !element ? loadMoreBtn.style.display = 'none' : newsList.appendChild(element.arDOMElement); } } function formatTime(timetxt){ const date = new Date(timetxt); const monthName = date.toLocaleString('en-US', {month: 'long'}); const datetxt = `${date.getDate()} ${monthName} ${date.getFullYear()}`; return datetxt; } function sortFun(type){ if(type === 'desc'){ items.sort((a,b) => { return a.sortableTime < b.sortableTime ? 1 : -1 }); return; } items.sort((a,b) => { return a.sortableTime > b.sortableTime ? 1 : -1 }); } function setupSorting(){ const select = document.querySelector('.articles-wrapper .sort-select'); ['click', 'keyup'].forEach(action => { select.addEventListener(action, ev => { if(ev.type === 'click' || ev.key === 'Enter'){ const isExpanded = select.getAttribute('aria-expanded') === 'true'; select.setAttribute('aria-expanded', !isExpanded); } }); }) const options = select.querySelectorAll('.options-wrapper *[role="option"]'); options.forEach(option => { ['click', 'keyup'].forEach(action => { option.addEventListener(action, ev => { if(ev.type === 'click' || ev.key === 'Enter'){ select.querySelector('[aria-selected="true"]').setAttribute('aria-selected', false); option.setAttribute('aria-selected', true); select.querySelector('.selected-sort > span').innerText = option.innerText; sortFun(option.getAttribute('value')); newsList.innerHTML = ''; addDomElements(true); } }); }); }); } } function interviewsContent(){ const items = []; const loadMoreBtn = document.querySelector('.interviews-wrapper .load-more'); let itemsDisplayed = 0; let interviewsList = document.querySelector('.section .interviews-grid'); const contentByLabel = document.querySelector('.interviews-cbl .content-by-label'); populateArray(); if(items.length > 3){ loadMoreBtn.style.display = 'flex'; } // descending order by date sortFun('desc'); setupSorting(); addDomElements(false); loadMoreBtn.addEventListener('click', ev => { addDomElements(false); }); contentByLabel.remove(); // functions function populateArray(){ try{ Array.from(contentByLabel.children).forEach(element => { const interCountry = element.querySelector('.details .exc-country').innerText; const interName = element.querySelector('.details .exc-name').innerText; const interProf = element.querySelector('.details .exc-prof').innerText; const interLink = `https://ec.europa.eu${element.querySelector('.details > a').getAttribute('href')}`; const interTime = formatTime(element.querySelector('.details time').innerText); const sortableTime = new Date(element.querySelector('.details time').innerText); const interPreview = element.querySelector('.details .exc-preview').innerText; const domElement = document.createElement('div'); domElement.classList.add('interview-item'); domElement.innerHTML = ` <img loading="lazy" class="interview-preview" src="${interPreview}" alt="" aria-hidden="true"> <div class="interview-details"> <h3 class="interview-country">${interCountry}</h3> <p class="interview-name"><img alt="Interviewee" src="/digital-building-blocks/sites/download/attachments/760938508/ico-person.svg"/> ${interName}</p> <p class="interview-prof">${interProf}</p> <a class="interview-link link-cta primary after" href="${interLink}"><span>Read interview</span></a> </div> `; items.push({ interCountry: interCountry, interName: interName, interProf: interProf, interLink: interLink, interTime: interTime, sortableTime: sortableTime, interPreview: interPreview, interDOMElement: domElement }); }); }catch(err){} } function addDomElements(flag){ // if flag = true, it will render elements from 0 to whatever value the itemsDisplayed was // (if you have clicked the load more button before - pretty much if you have clicked on sort). If false it will // start from the last itemsDisplayed value let num = 3; if(flag){ num = itemsDisplayed; } for (let index = 0; index < num; index++) { let element = items[itemsDisplayed]; if(flag){ element = items[index]; } if(!element){ loadMoreBtn.style.display = 'none'; break; } interviewsList.appendChild(element.interDOMElement); if(!flag){ itemsDisplayed++; } } } function formatTime(timetxt){ const date = new Date(timetxt); const monthName = date.toLocaleString('en-US', {month: 'long'}); const datetxt = `${date.getDate()} ${monthName} ${date.getFullYear()}`; return datetxt; } function sortFun(type){ if(type === 'desc'){ items.sort((a,b) => { return a.sortableTime < b.sortableTime ? 1 : -1 }); return; } items.sort((a,b) => { return a.sortableTime > b.sortableTime ? 1 : -1 }); } function setupSorting(){ const select = document.querySelector('.interviews-wrapper .sort-select'); ['click', 'keyup'].forEach(action => { select.addEventListener(action, ev => { if(ev.type === 'click' || ev.key === 'Enter'){ const isExpanded = select.getAttribute('aria-expanded') === 'true'; select.setAttribute('aria-expanded', !isExpanded); } }); }); const options = select.querySelectorAll('.options-wrapper *[role="option"]'); options.forEach(option => { ['click', 'keyup'].forEach(action => { option.addEventListener(action, ev => { if(ev.type === 'click' || ev.key === 'Enter'){ select.querySelector('[aria-selected="true"]').setAttribute('aria-selected', false); option.setAttribute('aria-selected', true); select.querySelector('.selected-sort > span').innerText = option.innerText; sortFun(option.getAttribute('value')); interviewsList.innerHTML = ''; addDomElements(true); } }); }); }); } } }); </script> |