diff --git a/.gitignore b/.gitignore index dd3445a19..b72023b10 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ logs/* helix-importer-ui .DS_Store *.bak +.env diff --git a/blocks/accordion/accordion.js b/blocks/accordion/accordion.js index 501c68115..504099273 100644 --- a/blocks/accordion/accordion.js +++ b/blocks/accordion/accordion.js @@ -12,43 +12,51 @@ function toggleAccordion(activeButton) { function createAccordionBlock(question, answer) { const uuid = generateUUID(); - const divEl = div(); + const divEl = dl(); const btn = dt( - { class: 'button peer', 'aria-expanded': false, 'aria-controls': `${uuid}` }, + { class: 'button peer py-4', 'aria-expanded': false, 'aria-controls': `${uuid}` }, button( { type: 'button', class: 'flex w-full items-start justify-between text-left text-gray-900' }, - h3({ class: 'text-base font-semibold leading-7' }, question), - span({ class: 'ml-6 flex h-14 items-center pr-2' }), + h3({ class: 'text-base font-semibold leading-7 my-0' }, question), + span({ class: 'ml-6 flex items-center pr-2 my-auto' }), ), ); btn.querySelector('span').innerHTML = ''; const panel = dd( - { id: `${uuid}`, class: 'panal mt-2 pr-12 pb-4 peer-[.show]:block hidden' }, + { id: `${uuid}`, class: 'panel pr-12 pb-4 peer-[.show]:block hidden' }, div({ class: 'accordion-answer text-base leading-7 text-gray-600 href-text' }), ); - panel.querySelector('.accordion-answer').innerHTML = answer; + + answer.forEach((element) => { + panel.querySelector('.accordion-answer').innerHTML += element; + }); btn.addEventListener('click', () => toggleAccordion(btn)); - divEl.append(document.createElement('hr'), btn, panel); + divEl.append(btn, panel); return divEl; } export default function decorate(block) { - const questions = [...block.children].map((element) => ({ - question: element.querySelector(':scope > div').children[0]?.textContent, - answer: element.querySelector(':scope > div').children[1]?.outerHTML, - })); + const questions = [...block.children].map((element) => { + const questionElement = element.querySelector(':scope > div > h3'); + const answerElements = Array.from(element.querySelector(':scope > div').children).slice(1); + return { + question: questionElement?.textContent, + answer: answerElements.map((elem) => elem.outerHTML), + }; + }); - const accordionItems = questions + const filteredQuestions = questions.filter((item) => item.question !== undefined); + const accordionItems = filteredQuestions .map((question, index) => createAccordionBlock(question.question, question.answer, index)); - const accordion = dl( - { class: 'space-y-4 divide-y divide-gray-900/10' }, - div({ class: 'pt-6' }), + const accordion = div( + { class: 'divide-y divide-gray-900/10' }, + ...accordionItems, ); - accordionItems.map((items) => accordion.querySelector('div.pt-6').append(items)); + const title = [...block.children][0].querySelector(':scope > div > h2'); block.innerHTML = ''; - block.className = 'divide-y divide-gray-900/10'; + if (title && title.textContent) block.append(title, document.createElement('hr')); block.append(accordion); } diff --git a/blocks/banner/banner.js b/blocks/banner/banner.js index 3ae19e081..871b82cb7 100644 --- a/blocks/banner/banner.js +++ b/blocks/banner/banner.js @@ -1,4 +1,4 @@ export default function decorate(block) { const main = document.querySelector('main'); - main.prepend(block); + main.parentNode.insertBefore(block, main); } diff --git a/blocks/blog-hero/blog-hero.css b/blocks/blog-hero/blog-hero.css deleted file mode 100644 index 34c9995fb..000000000 --- a/blocks/blog-hero/blog-hero.css +++ /dev/null @@ -1,3 +0,0 @@ -.blog-hero h1 + p { - @apply text-xl text-gray-500 leading-8; -} \ No newline at end of file diff --git a/blocks/blog-hero/blog-hero.js b/blocks/blog-hero/blog-hero.js index c6b2d6a0f..b7fd8c3db 100644 --- a/blocks/blog-hero/blog-hero.js +++ b/blocks/blog-hero/blog-hero.js @@ -4,8 +4,9 @@ import { import { getMetadata } from '../../scripts/lib-franklin.js'; export default function decorate(block) { - if (block.querySelector('h1')) block.querySelector('h1').className = 'px-2 text-gray-900 my-2 font-extrabold text-4xl'; - if (block.querySelector('img')) block.querySelector('img').className = 'px-2 mt-8'; + if (block.querySelector('h1')) block.querySelector('h1').classList.add(...'px-2 text-gray-900 my-2 font-extrabold text-4xl'.split(' ')); + if (block.querySelector('h1 + p')) block.querySelector('h1 + p').classList.add(...'px-2 text-xl text-gray-500 leading-8'.split(' ')); + if (block.querySelector('img')) block.querySelector('img').classList.add(...'px-2 mt-8'.split(' ')); const authorName = getMetadata('authorname'); const authorJobTitle = getMetadata('authortitle'); diff --git a/blocks/breadcrumb/breadcrumb.js b/blocks/breadcrumb/breadcrumb.js index d78a392a5..9a1605287 100644 --- a/blocks/breadcrumb/breadcrumb.js +++ b/blocks/breadcrumb/breadcrumb.js @@ -1,26 +1,27 @@ export default function decorate(block) { - const clonedBlock = block.cloneNode(true); - const listsClone = clonedBlock.querySelector('div > ul').cloneNode(true); - listsClone.className = 'max-w-screen-xl w-full mx-auto px-4 flex gap-4 sm:px-6 lg:px-7 overflow-x-auto'; - listsClone.setAttribute('role', 'list'); + const entries = block.querySelector('div > ul'); + entries.className = 'max-w-screen-xl w-full mx-auto px-4 flex gap-4 sm:px-6 lg:px-7 overflow-x-auto'; + entries.setAttribute('role', 'list'); const homeIconLi = document.createElement('li'); homeIconLi.className = 'flex items-center gap-x-3 text-sm font-medium text-gray-500 whitespace-nowrap hover:text-gray-700'; homeIconLi.innerHTML = ''; - listsClone.prepend(homeIconLi); - Array.from(listsClone.children).forEach((element, index) => { + entries.prepend(homeIconLi); + Array.from(entries.children).forEach((element, index) => { element.classList.add(...'flex items-center gap-x-3 text-sm font-medium text-gray-500 whitespace-nowrap hover:text-gray-700'.split(' ')); element.setAttribute('aria-hidden', 'true'); element.setAttribute('data-acsb-hidden', 'true'); element.setAttribute('data-acsb-force-hidden', 'true'); const anchor = element.children[0]; anchor.setAttribute('tabindex', '-1'); - if ((listsClone.children.length - 1) !== index) element.innerHTML = ""; + if ((entries.children.length - 1) !== index) element.innerHTML = ""; element.prepend(anchor); }); - const breadcrumbWrapper = document.getElementsByClassName('breadcrumb-wrapper')[0]; + const breadcrumbWrapper = block.parentElement; breadcrumbWrapper.classList.add(...'flex bg-white border-b border-gray-200'.split(' ')); breadcrumbWrapper.innerHTML = ''; - breadcrumbWrapper.append(listsClone); + breadcrumbWrapper.append(entries); + const breadcrumbSection = breadcrumbWrapper.parentElement; const mainElement = document.querySelector('main'); mainElement.parentNode.insertBefore(breadcrumbWrapper, mainElement); + breadcrumbSection.remove(); } diff --git a/blocks/call-to-action/call-to-action.js b/blocks/call-to-action/call-to-action.js index c22c85e6e..c9f253390 100644 --- a/blocks/call-to-action/call-to-action.js +++ b/blocks/call-to-action/call-to-action.js @@ -1,9 +1,15 @@ import { decorateModals } from '../../scripts/scripts.js'; export default function decorate(block) { - block.classList.add(...'ctasection mx-auto max-w-7xl lg:py-8'.split(' ')); + block.classList.add(...'ctasection mx-auto max-w-7xl pt-6 lg:py-8'.split(' ')); block.querySelector(':scope div > div').classList.add(...'md:flex space-y-8 md:space-y-0 md:flex-row w-full py-8 md:py-16 md:px-12 px-6 items-center md:justify-between bg-danaherpurple-800'.split(' ')); - block.querySelector('h2').classList.add(...'text-2xl p-0 m-0 tracking-tight sm:text-3xl text-white font-normal tracking-wide'.split(' ')); - block.querySelector('p').classList.add(...'show-modal-btn btn btn-outline-trending-brand text-lg rounded-full px-6 py-3'.split(' ')); + block.querySelector('h2')?.classList.add(...'text-2xl p-0 m-0 tracking-tight sm:text-3xl text-white font-normal tracking-wide'.split(' ')); + block.querySelectorAll('p > a').forEach((a) => { + a.classList.add(...'btn-outline-trending-brand text-lg rounded-full px-6 py-3 !no-underline'.split(' ')); + if (a.href.includes('#request-quote')) { + block.querySelector('p')?.classList.add(...'show-modal-btn'.split(' ')); + a.classList.remove(...'btn btn-outline-primary'.split(' ')); + } + }); decorateModals(block); } diff --git a/blocks/card-list/applicationCard.js b/blocks/card-list/applicationCard.js new file mode 100644 index 000000000..914713ea9 --- /dev/null +++ b/blocks/card-list/applicationCard.js @@ -0,0 +1,40 @@ +import { makePublicUrl } from '../../scripts/scripts.js'; +import { + li, a, p, div, h2, +} from '../../scripts/dom-builder.js'; + +export default function createCard(article) { + const cardTitle = article.title.indexOf('| Danaher Life Sciences') > -1 + ? article.title.split('| Danaher Life Sciences')[0] + : article.title; + + const cardWrapper = a( + { href: makePublicUrl(article.path), title: article.title }, + h2( + { + class: + '!px-6 !text-lg !font-semibold !text-danahergray-900 !mb-4 !line-clamp-3 !h-20 !break-words', + }, + cardTitle, + ), + p( + { class: 'px-6 text-sm text-gray-500 pb-0 pt-0 pb-4 line-clamp-4 h-20 break-words' }, + article.description, + ), + div( + { + class: + 'inline-flex w-full px-6 py-5 text-base text-danaherblue-600 font-semibold', + }, + 'View Application →', + ), + ); + + return li( + { + class: + 'w-full flex flex-col col-span-1 relative mx-auto justify-center transform transition duration-500 border hover:scale-105 shadow-lg rounded-lg overflow-hidden bg-white max-w-xl', + }, + cardWrapper, + ); +} diff --git a/blocks/card-list/articleCard.js b/blocks/card-list/articleCard.js new file mode 100644 index 000000000..7ee2a775e --- /dev/null +++ b/blocks/card-list/articleCard.js @@ -0,0 +1,49 @@ +import { formatDateUTCSeconds, imageHelper, makePublicUrl } from '../../scripts/scripts.js'; +import { + li, a, p, div, time, span, h2, +} from '../../scripts/dom-builder.js'; + +export default function createCard(article, firstCard = false) { + const cardTitle = article.title.indexOf('| Danaher Life Sciences') > -1 + ? article.title.split('| Danaher Life Sciences')[0] + : article.title; + + const cardWrapper = a( + { href: makePublicUrl(article.path), title: article.title }, + imageHelper(article.image, article.title, firstCard), + p( + { class: 'cards !px-6 !py-1 !pt-4 !text-sm !text-danaherpurple-500' }, + article.brand || 'Danaher Corporation', + ), + p( + { class: '!px-6 !pb-3 !text-gray-500 !text-sm' }, + time( + { datetime: formatDateUTCSeconds(article.publishDate) }, + formatDateUTCSeconds(article.publishDate, { month: 'long' }), + ), + span({ class: 'pl-2' }, `${article.readingTime} min read`), + ), + h2( + { + class: + '!px-6 !text-lg !font-semibold !text-danahergray-900 !mb-4 !line-clamp-3 !h-20 !break-words', + }, + cardTitle, + ), + div( + { + class: + 'mt-auto inline-flex w-full px-6 py-5 text-base text-danaherpurple-500 font-semibold', + }, + 'Read Article →', + ), + ); + + return li( + { + class: + 'w-full flex flex-col col-span-1 relative mx-auto justify-center transform transition duration-500 border hover:scale-105 shadow-lg rounded-lg overflow-hidden bg-white max-w-xl', + }, + cardWrapper, + ); +} diff --git a/blocks/card-list/card-list.js b/blocks/card-list/card-list.js index 562983317..fa629c7ca 100644 --- a/blocks/card-list/card-list.js +++ b/blocks/card-list/card-list.js @@ -1,50 +1,15 @@ import ffetch from '../../scripts/ffetch.js'; import { - ul, li, a, p, div, time, span, h2, + ul, a, div, span, h2, } from '../../scripts/dom-builder.js'; -import { formatDateUTCSeconds, makePublicUrl, imageHelper } from '../../scripts/scripts.js'; + import { toClassName } from '../../scripts/lib-franklin.js'; +import createArticleCard from './articleCard.js'; +import createApplicationCard from './applicationCard.js'; +import createLibraryCard from './libraryCard.js'; const getSelectionFromUrl = (field) => toClassName(new URLSearchParams(window.location.search).get(field)) || ''; -export function createCard(article, firstCard = false) { - const cardTitle = article.title.indexOf('| Danaher Life Sciences') > -1 - ? article.title.split('| Danaher Life Sciences')[0] - : article.title; - - const cardWrapper = a( - { href: makePublicUrl(article.path), title: article.title }, - imageHelper(article.image, article.title, firstCard), - p( - { class: 'cards !px-6 !py-1 !pt-4 !text-sm !text-danaherpurple-500' }, - article.brand || 'Danaher Corporation', - ), - p( - { class: '!px-6 !pb-3 !text-gray-500 !text-sm' }, - time( - { datetime: formatDateUTCSeconds(article.publishDate) }, - formatDateUTCSeconds(article.publishDate, { month: 'long' }), - ), - span({ class: 'pl-2' }, `${article.readingTime} min read`), - ), - h2( - { - class: '!px-6 !text-lg !font-semibold !text-danahergray-900 !mb-4 !line-clamp-3 !h-20 !break-words', - }, - cardTitle, - ), - div( - { class: 'mt-auto inline-flex w-full px-6 py-5 text-base text-danaherpurple-500 font-semibold' }, - 'Read Article →', - ), - ); - - return li({ - class: - 'w-full flex flex-col col-span-1 relative mx-auto justify-center transform transition duration-500 border hover:scale-105 shadow-lg rounded-lg overflow-hidden bg-white max-w-xl', - }, cardWrapper); -} - const createPaginationLink = (page, label, current = false) => { const newUrl = new URL(window.location); newUrl.searchParams.set('page', page); @@ -149,6 +114,8 @@ const createFilters = (articles, activeTag) => { export default async function decorate(block) { const articleType = block.classList.length > 2 ? block.classList[1] : ''; if (articleType) block.classList.remove(articleType); + block.textContent = ''; + // fetch and sort all articles const articles = await ffetch('/us/en/article-index.json') .chunks(500) @@ -161,28 +128,72 @@ export default async function decorate(block) { (item) => toClassName(item.keywords).toLowerCase().indexOf(activeTagFilter) > -1, ); } - filteredArticles.sort((card1, card2) => card2.publishDate - card1.publishDate); - - // handle pagination - let page = parseInt(getSelectionFromUrl('page'), 10); - page = Number.isNaN(page) ? 1 : page; - const limitPerPage = 20; - const start = (page - 1) * limitPerPage; - const articlesToDisplay = filteredArticles.slice(start, start + limitPerPage); - - // render cards - const cardList = ul({ - class: - 'container grid max-w-7xl w-full mx-auto gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 px-4 sm:px-0 justify-items-center mt-3 mb-3', - }); - articlesToDisplay.forEach((article, index) => { - cardList.appendChild(createCard(article, index === 0)); - }); - // render pagination and filters - const filterTags = createFilters(articles, activeTagFilter); - const paginationElements = createPagination(filteredArticles, page, limitPerPage); + // render cards library style + if (articleType === 'library') { + block.classList.add(...'flex flex-col md:flex-wrap md:flex-row'.split(' ')); + filteredArticles.sort((card1, card2) => card1.title.localeCompare(card2.title)); + + // map filteredArticles to a new map with first letter as key + const filteredArticlesMap = new Map(); + filteredArticles.forEach((card) => { + const firstLetter = card.title[0]?.toUpperCase(); + if (!filteredArticlesMap.has(firstLetter)) { + filteredArticlesMap.set(firstLetter, []); + } + filteredArticlesMap.get(firstLetter).push(card); + }); - block.textContent = ''; - block.append(filterTags, cardList, paginationElements); + // iterate over map and create a new array of cards + filteredArticlesMap.forEach((cards, letter) => { + const cardList = ul({ + class: + 'grid max-w-7xl w-full md:w-3/4 mx-auto gap-6 grid-cols-1 lg:grid-cols-3 px-4 sm:px-0 justify-items-center mb-16', + }); + const divLetter = div( + { class: 'md:w-1/4 mb-8 px-4 md:px-0 md:text-right md:pr-8' }, + h2({ class: 'text-2xl font-extrabold md:border-t mt-0', id: `letter-${letter}` }, letter), + ); + const ifFirstLetter = letter === filteredArticlesMap.keys().next().value; + cards.forEach((card, index) => { + cardList.appendChild(createLibraryCard(card, index === 0 && ifFirstLetter)); + }); + block.append(divLetter, cardList); + }); + // render cards application style + } else if (articleType === 'application') { + filteredArticles.sort((card1, card2) => card1.title.localeCompare(card2.title)); + + const cardList = ul({ + class: + 'container grid max-w-7xl w-full mx-auto gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 px-4 sm:px-0 justify-items-center mt-3 mb-3', + }); + filteredArticles.forEach((article) => { + cardList.appendChild(createApplicationCard(article)); + }); + block.append(cardList); + // render cards article style + } else { + filteredArticles.sort((card1, card2) => card2.publishDate - card1.publishDate); + + let page = parseInt(getSelectionFromUrl('page'), 10); + page = Number.isNaN(page) ? 1 : page; + const limitPerPage = 20; + const start = (page - 1) * limitPerPage; + const articlesToDisplay = filteredArticles.slice(start, start + limitPerPage); + + const cardList = ul({ + class: + 'container grid max-w-7xl w-full mx-auto gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 px-4 sm:px-0 justify-items-center mt-3 mb-3', + }); + articlesToDisplay.forEach((article, index) => { + cardList.appendChild(createArticleCard(article, index === 0)); + }); + + // render pagination and filters + const filterTags = createFilters(articles, activeTagFilter); + const paginationElements = createPagination(filteredArticles, page, limitPerPage); + + block.append(filterTags, cardList, paginationElements); + } } diff --git a/blocks/card-list/libraryCard.js b/blocks/card-list/libraryCard.js new file mode 100644 index 000000000..eb9c78b05 --- /dev/null +++ b/blocks/card-list/libraryCard.js @@ -0,0 +1,46 @@ +import { makePublicUrl } from '../../scripts/scripts.js'; +import { createOptimizedPicture } from '../../scripts/lib-franklin.js'; +import { + li, a, p, div, h2, +} from '../../scripts/dom-builder.js'; + +export default function createCard(article, firstCard = false) { + const cardTitle = article.title.indexOf('| Danaher Life Sciences') > -1 + ? article.title.split('| Danaher Life Sciences')[0] + : article.title.trim(); + const cardImage = createOptimizedPicture(article.image, article.title, firstCard, [{ media: '(min-width: 1024px)', width: '320' }, { media: '(min-width: 640px)', width: '520' }, { width: '420' }]); + cardImage.querySelector('img').className = 'mb-2 h-48 w-full object-cover'; + + const cardWrapper = a( + { href: makePublicUrl(article.path), title: article.title }, + cardImage, + h2( + { + class: + '!px-6 !text-lg !font-semibold !text-danahergray-900 !mb-4 !line-clamp-3 !h-20 !break-words', + }, + cardTitle, + ), + article.description ? p( + { + class: 'px-6 text-sm text-gray-500 pb-0 pt-0 pb-4 line-clamp-4 h-20 break-words', + }, + article.description, + ) : '', + div( + { + class: + 'mt-auto inline-flex w-full px-6 py-5 text-base text-danaherpurple-500 font-semibold', + }, + 'Learn More →', + ), + ); + + return li( + { + class: + 'w-full flex flex-col col-span-1 relative mx-auto justify-center transform transition duration-500 border hover:scale-105 shadow-lg rounded-lg overflow-hidden bg-white max-w-xl', + }, + cardWrapper, + ); +} diff --git a/blocks/header/header.js b/blocks/header/header.js index 28c0d3c9b..82f354b79 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -443,6 +443,7 @@ function buildSearchBlock(headerBlock) { const logoPictureBlock = searchHtmlBlock.querySelector(':scope > p > picture'); const logoLinkBlock = searchHtmlBlock.querySelector(':scope > p > a'); logoPictureBlock.setAttribute('alt', logoLinkBlock.textContent); + if (window.location.pathname === '/') logoLinkBlock.href = 'https://danaher.com/?utm_source=dhls_website&utm_medium=referral&utm_content=header'; const logoImg = logoPictureBlock.querySelector('img'); logoImg.className = 'brand-logo max-w-full w-14 md:w-20 lg:w-44 h-full object-contain'; logoLinkBlock.className = 'ml-2 mb-2'; diff --git a/blocks/recent-articles/recent-articles.js b/blocks/recent-articles/recent-articles.js index 9a098fbf4..e0559bf2e 100644 --- a/blocks/recent-articles/recent-articles.js +++ b/blocks/recent-articles/recent-articles.js @@ -33,8 +33,8 @@ export default async function decorate(block) { p({ class: 'text-sm font-medium text-danahergray-500 pb-2 my-0' }, article.title), p( { class: 'flex justify-between items-cente my-0' }, - span({ class: 'text-sm text-gray-700 font-normal' }, formatDateUTCSeconds(article.publishDate)), - span({ class: 'flex items-center text-xs font-semibold text-danaherblue-600', id: 'read-article' }), + span({ class: 'text-sm text-gray-700 font-normal' }, !(articleType === 'library' || articleType === 'info') ? formatDateUTCSeconds(article.publishDate) : ''), + span({ class: 'flex items-right text-xs font-semibold text-danaherblue-600', id: 'read-article' }), ), ), ); diff --git a/blocks/related-articles/related-articles.js b/blocks/related-articles/related-articles.js index a44314439..1d911e8a4 100644 --- a/blocks/related-articles/related-articles.js +++ b/blocks/related-articles/related-articles.js @@ -3,7 +3,7 @@ import { getMetadata } from '../../scripts/lib-franklin.js'; import { ul, span, } from '../../scripts/dom-builder.js'; -import { createCard } from '../card-list/card-list.js'; +import createCard from '../card-list/articleCard.js'; export default async function decorate(block) { const articleType = getMetadata('template').toLowerCase(); diff --git a/blocks/side-nav/side-nav.js b/blocks/side-nav/side-nav.js new file mode 100644 index 000000000..bb1865b8e --- /dev/null +++ b/blocks/side-nav/side-nav.js @@ -0,0 +1,57 @@ +import { div, a, strong } from '../../scripts/dom-builder.js'; +import ffetch from '../../scripts/ffetch.js'; +import { getMetadata } from '../../scripts/lib-franklin.js'; +import { makePublicUrl } from '../../scripts/scripts.js'; +import { fetchTopicsForCategory } from '../topic-list/topic-list.js'; + +async function fetchAllProductCategories() { + const topicHubs = await ffetch('/us/en/products-index.json') + .filter(({ type }) => type === 'TopicHub') + .all(); + return topicHubs.sort((item1, item2) => item1.title.localeCompare(item2.title)); +} + +function renderSideNav(sideNavItems) { + const sideNavElements = div({ class: 'flex flex-col items-start' }); + sideNavItems.forEach((sideNavItem) => { + sideNavElements.append(div( + { + class: 'w-full side-nav-item hover:bg-danaherpurple-25 hover:rounded-md', + }, + div( + { + class: 'flex gap-3', + }, + a({ + class: 'px-6 py-2 text-base', + href: makePublicUrl(sideNavItem.path), + }, sideNavItem.title), + ), + )); + }); + return sideNavElements; +} + +export default async function decorate(block) { + let sideNavItems = []; + let sideNavTitle = 'Side Navigation'; + let selectedNavItem = null; + let sideNavElements = div(); + if (block.classList.contains('topics')) { + const category = getMetadata('fullcategory'); + sideNavItems = await fetchTopicsForCategory(category); + const categoryObj = await ffetch('/us/en/products-index.json') + .filter(({ path }) => path === `/us/en/products/${category}`) + .first(); + sideNavTitle = categoryObj?.title || category || sideNavTitle; + } else if (block.classList.contains('products')) { + sideNavItems = await fetchAllProductCategories(); + sideNavTitle = 'Products'; + } + sideNavElements = renderSideNav(sideNavItems); + selectedNavItem = sideNavElements.querySelector(`.side-nav-item a[href="${window.location.pathname}"]`)?.closest('.side-nav-item'); + if (selectedNavItem) selectedNavItem.classList.add('font-bold', 'bg-danaherpurple-50', 'hover:bg-danaherpurple-50', 'rounded-md'); + block.append(div({ class: 'text-lg px-5 py-4' }, strong(sideNavTitle)), sideNavElements); + block.classList.add('pt-6', 'pr-2'); + return block; +} diff --git a/blocks/table/table.js b/blocks/table/table.js index bf7853b75..d6653c2de 100644 --- a/blocks/table/table.js +++ b/blocks/table/table.js @@ -7,25 +7,28 @@ import { } from '../../scripts/dom-builder.js'; function buildCell(rowIndex) { - const cell = rowIndex ? td({ class: 'text-left text-gray-900' }) : th({ class: 'text-left text-gray-900 font-normal' }); + const cell = rowIndex ? td({ class: 'text-left text-gray-700 p-2' }) : th({ class: 'text-left text-gray-700 font-bold p-2' }); if (!rowIndex) cell.setAttribute('scope', 'col'); return cell; } export default async function decorate(block) { const t = table({ - class: 'w-full max-w-full', + class: 'table-auto w-full max-w-full', cellpadding: 1, cellspacing: 0, border: 1, }); const head = thead(); - const body = tbody(); + const body = tbody({ class: 'divide-y divide-gray-200' }); t.append(head, body); [...block.children].forEach((child, i) => { const row = tr(); if (i) body.append(row); - else head.append(row); + else { + row.classList.add(...'border-b border-b-gray-200'.split(' ')); + head.append(row); + } [...child.children].forEach((col) => { const cell = buildCell(i); cell.innerHTML = col.innerHTML; diff --git a/blocks/takeway/takeway.js b/blocks/takeway/takeway.js new file mode 100644 index 000000000..2d9e32a6d --- /dev/null +++ b/blocks/takeway/takeway.js @@ -0,0 +1,3 @@ +export default function decorate(block) { + block.classList.add(...'mb-20 bg-danaherpurple-50 border-t-8 border-danaherpurple-500 px-6 lg:px-10 py-6 space-y-4 leading-7 text-base text-danahergray-700'.split(' ')); +} diff --git a/blocks/topic-list/topic-list.js b/blocks/topic-list/topic-list.js new file mode 100644 index 000000000..5ac272384 --- /dev/null +++ b/blocks/topic-list/topic-list.js @@ -0,0 +1,46 @@ +import { + a, div, h2, hr, +} from '../../scripts/dom-builder.js'; +import ffetch from '../../scripts/ffetch.js'; +import { getMetadata } from '../../scripts/lib-franklin.js'; +import { makePublicUrl } from '../../scripts/scripts.js'; + +export async function fetchTopicsForCategory(category) { + if (!category) return []; + const topics = await ffetch('/us/en/products-index.json') + .filter(({ fullCategory, type }) => fullCategory === category && type === 'Topic') + .all(); + return topics.sort((item1, item2) => item1.title.localeCompare(item2.title)); +} + +export default async function decorate(block) { + const category = getMetadata('fullcategory'); + const topics = await fetchTopicsForCategory(category); + block.classList.add('pt-10', 'pb-10'); + block.append(hr({ class: 'h-1 bg-black' })); + const topicCards = div({ class: 'flex flex-col items-start' }); + topics.forEach((topic) => { + topicCards.append(div( + { + class: 'w-full', + }, + div( + { + class: 'flex items-center gap-3 py-9', + }, + h2({ class: 'text-xl' }, topic.title), + div( + { + class: 'flex min-w-[40%] md:min-w-[20%] ml-auto', + }, + a({ + class: 'rounded-full px-6 py-3 ml-auto btn-outline-trending-brand text-base', + href: makePublicUrl(topic.path), + }, 'Read Topic'), + ), + ), + hr(), + )); + }); + block.append(topicCards); +} diff --git a/blocks/we-see/we-see.js b/blocks/we-see/we-see.js index 45a42a103..a51a69352 100644 --- a/blocks/we-see/we-see.js +++ b/blocks/we-see/we-see.js @@ -2,19 +2,6 @@ import { loadScript } from '../../scripts/lib-franklin.js'; import { getFragmentFromFile } from '../../scripts/scripts.js'; export default async function decorate(block) { - const url = block.querySelector('a').href; - if (new URL(url).origin !== window.location.origin) { - block.innerHTML = '

Cannot use unsafe cross-origin reference for the HTML Snippets.

'; - return; - } - - if (!url) { - block.textContent = ''; - // eslint-disable-next-line no-console - console.warn('no snippet found'); - return; - } - try { // get the content const fragment = await getFragmentFromFile('/fragments/wesee.html'); @@ -38,6 +25,6 @@ export default async function decorate(block) { } catch (e) { block.textContent = ''; // eslint-disable-next-line no-console - console.warn(`cannot load snippet at ${url}: ${e}`); + console.warn(`cannot load we see snippet: ${e}`); } } diff --git a/fragments/footer.html b/fragments/footer.html index ac9629123..62acd9e11 100644 --- a/fragments/footer.html +++ b/fragments/footer.html @@ -36,7 +36,7 @@

diff --git a/helix-query.yaml b/helix-query.yaml index c23181eea..7f54c2ee0 100644 --- a/helix-query.yaml +++ b/helix-query.yaml @@ -5,14 +5,19 @@ indices: - /us/en/blog/** - /us/en/news/** - /us/en/library/** + - /us/en/application/** + - /us/en/info/** target: /us/en/article-index.json properties: lastModified: select: none value: parseTimestamp(headers["last-modified"], "ddd, DD MMM YYYY hh:mm:ss GMT") title: - select: head > meta[property="og:title"] - value: match(attribute(el, "content"), "(.*)\\\| Danaher Life.*") + select: main h1 + value: textContent(el) + description: + select: head > meta[name="description"] + value: attribute(el, "content") image: select: head > meta[property="og:image"] value: match(attribute(el, "content"), "^(https?:\/\/.*?(danaher.com))+(.*)|^(.*)") diff --git a/scripts/dom-builder.js b/scripts/dom-builder.js index deb453e0c..302f33f75 100644 --- a/scripts/dom-builder.js +++ b/scripts/dom-builder.js @@ -96,3 +96,4 @@ export function textarea(...items) { return domEl('textarea', ...items); } export function dl(...items) { return domEl('dl', ...items); } export function dt(...items) { return domEl('dt', ...items); } export function dd(...items) { return domEl('dd', ...items); } +export function hr(...items) { return domEl('hr', ...items); } diff --git a/scripts/lib-franklin.js b/scripts/lib-franklin.js index 5505ee60a..902aaef92 100644 --- a/scripts/lib-franklin.js +++ b/scripts/lib-franklin.js @@ -655,7 +655,7 @@ export function decorateButtons(element) { if (a.href !== a.textContent) { const up = a.parentElement; const twoup = a.parentElement.parentElement; - if (!a.querySelector('img')) { + if (!a.querySelector('img') && twoup.tagName !== 'LI' && !a.closest('.call-to-action')) { if (up.childNodes.length === 1 && (up.tagName === 'P' || up.tagName === 'DIV')) { a.className = 'btn btn-outline-primary'; // default up.classList.add('button-container'); diff --git a/scripts/scripts.js b/scripts/scripts.js index e1be36a14..45d87b9e6 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -30,6 +30,8 @@ const TEMPLATE_LIST = { blog: 'blog', news: 'blog', topic: 'topic', + library: 'library', + info: 'library', }; /** diff --git a/styles/styles.css b/styles/styles.css index 5bc2f84e2..c7c40735c 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -82,6 +82,10 @@ padding-bottom: 2.5rem; } +.blog main .section:empty { + display: none; +} + @media (min-width: 640px) { .blog main .section { @@ -101,154 +105,17 @@ .blog main .default-content-wrapper h1:first-child { margin-top: 0px; margin-bottom: 0.5rem; - font-size: 2.25rem; - line-height: 2.5rem; - font-weight: 800; - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); -} - -.blog main .default-content-wrapper p:not(:first-of-type) { - margin-top: 0.75rem; - font-size: 1rem; - line-height: 1.75rem; - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); -} - -.blog main .default-content-wrapper img:first-child { - margin-top: 0.5rem; - margin-bottom: 1rem; -} - -.blog main .default-content-wrapper h2 { - display: inline-flex; - font-size: 1.25rem; - line-height: 1.75rem; - font-weight: 600; - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); } .blog main p { margin-top: 0.75rem; - font-size: 1rem; - line-height: 1.75rem; - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); } -.blog main p a { - position: relative; - z-index: 0; - word-break: break-all; - text-decoration-line: underline; - text-decoration-color: #3bc7e5; - text-decoration-thickness: 3px; -} - -.blog main p a:hover { - --tw-bg-opacity: 1; - background-color: rgb(59 199 229 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-duration: 150ms; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); -} - -.blog main .default-content-wrapper p { +.blog main .default-content-wrapper > * { padding-left: 0.5rem !important; padding-right: 0.5rem !important; } -.blog main h2 { - display: inline-flex; - font-size: 1.25rem; - line-height: 1.75rem; - font-weight: 600; - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); -} - -.blog main a { - font-weight: 600; -} - -.blog main p.button-container>a { - margin-top: 1.5rem; - border-radius: 9999px; - border-width: 1px; - --tw-border-opacity: 1; - border-color: rgb(117 35 255 / var(--tw-border-opacity)); - background-color: transparent; - padding-left: 1.25rem; - padding-right: 1.25rem; - padding-top: 0.75rem; - padding-bottom: 0.75rem; - font-size: 1.125rem; - font-weight: 500; - line-height: 1.25rem; - --tw-text-opacity: 1; - color: rgb(117 35 255 / var(--tw-text-opacity)); - text-decoration-line: none; - transition-property: all; - transition-duration: 150ms; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); -} - -.blog main p.button-container>a:hover { - --tw-bg-opacity: 1; - background-color: rgb(117 35 255 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.blog main .default-content-wrapper ol, .blog main .default-content-wrapper ul { - margin-top: 0.75rem; - margin-left: 3rem; - list-style-position: outside; - font-size: 1rem; - line-height: 1.75rem; - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); -} - -.blog main .default-content-wrapper ol a, .blog main .default-content-wrapper ul a { - position: relative; - z-index: 0; - word-break: break-all; - text-decoration-line: underline; - text-decoration-color: #3bc7e5; - text-decoration-thickness: 3px; -} - -.blog main .default-content-wrapper ol a:hover, .blog main .default-content-wrapper ul a:hover { - --tw-bg-opacity: 1; - background-color: rgb(59 199 229 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-duration: 150ms; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); -} - -.blog main .default-content-wrapper ol>li, .blog main .default-content-wrapper ul>li { - margin-bottom: 0.25rem; -} - -.blog main .default-content-wrapper ol { - list-style-type: decimal; -} - -.blog main .default-content-wrapper ul { - list-style-type: disc; -} - .blog main .popular-articles { display: none; flex-shrink: 0; @@ -266,46 +133,9 @@ } } -.topic main { - margin-left: auto; - margin-right: auto; - display: flex; - max-width: 80rem; - flex-direction: column; - padding-left: 1rem; - padding-right: 1rem; -} - -.testimonial .testimonial-footer .topic main>div:nth-child(2) { - margin-top: 0px; - font-size: 1rem; - font-weight: 500; - line-height: 1.5rem; - --tw-text-opacity: 1; - color: rgb(2 105 124 / var(--tw-text-opacity)); -} - -@media (min-width: 1024px) { - - .topic main { - padding-left: 0px; - padding-right: 0px; - } -} - -.topic main .section { - flex: 1 1 0%; - padding: 0px; - padding-left: 0px; -} - -@media (min-width: 1024px) { - - .topic main .section { - margin-left: auto; - width: 75%; - padding-left: 1.5rem; - } +.blog main .table { + padding-top: 1.5rem; + padding-bottom: 1.5rem; } .topic main .button-container a { @@ -337,72 +167,13 @@ line-height: 1.75rem; } -.topic main > div:first-child { - margin-bottom: 0.5rem; -} - -.topic main > div:first-child > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); -} - -.topic main > div:first-child .default-content-wrapper h1 { +.topic main .default-content-wrapper h1 { margin-top: 0.5rem; margin-bottom: 0.5rem; padding-top: 0.5rem; padding-bottom: 0.5rem; padding-left: 0px; padding-right: 0px; - font-size: 2.25rem; - line-height: 2.5rem; - font-weight: 800; - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); -} - -.product-topic-takeaway .default-content-wrapper { - margin-bottom: 5rem; -} - -.product-topic-takeaway .default-content-wrapper > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); -} - -.product-topic-takeaway .default-content-wrapper { - border-top-width: 8px; - --tw-border-opacity: 1; - border-color: rgb(117 35 255 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(234 222 255 / var(--tw-bg-opacity)); - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 1.5rem; - padding-bottom: 1.5rem; - font-size: 1rem; - line-height: 1.75rem; - --tw-text-opacity: 1; - color: rgb(55 65 81 / var(--tw-text-opacity)); -} - -@media (min-width: 1024px) { - - .product-topic-takeaway .default-content-wrapper { - padding-left: 2.5rem; - padding-right: 2.5rem; - } -} - -*:has(.product-topic-takeaway) .default-content-wrapper h2 { - margin-top: 0px; - margin-bottom: 0px; - font-size: 1.25rem; - line-height: 1.75rem; - font-weight: 600; - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); } .topic main p:not(.show-modal-btn) { @@ -424,6 +195,41 @@ width: 100%; } +.library main { + margin-left: auto; + margin-right: auto; + display: flex; + width: 100%; + max-width: 80rem; + flex-direction: row; + gap: 2.5rem; + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.library main .section { + padding-left: 0px; +} + +.library main .section .call-to-action-wrapper h2 { + margin: 0px; + padding: 0px; + font-size: 1.5rem !important; + line-height: 2rem !important; + font-weight: 400; + letter-spacing: 0.025em; + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +@media (min-width: 640px) { + + .library main .section .call-to-action-wrapper h2 { + font-size: 1.875rem; + line-height: 2.25rem; + } +} + .testimonial>div { display: flex; align-items: center; @@ -944,13 +750,6 @@ button.suggestion.selected { background-color: rgb(243 244 246 / var(--tw-bg-opacity)); } -.blog-hero h1 + p { - font-size: 1.25rem; - line-height: 2rem; - --tw-text-opacity: 1; - color: rgb(107 114 128 / var(--tw-text-opacity)); -} - .block.social-media { position: relative; z-index: 10; @@ -1558,6 +1357,22 @@ h6 { font-weight: 400; } +main .default-content-wrapper h1 { + font-size: 2.25rem; + line-height: 2.5rem; + font-weight: 800; + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); +} + +main .default-content-wrapper h2, main .accordion-wrapper h2 { + font-size: 1.875rem; + line-height: 2.25rem; + font-weight: 500; + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); +} + *, ::before, ::after { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; @@ -1791,43 +1606,6 @@ main .section { outline-offset: 2px; } -/* START OF TEMP STYLES */ - -.btn.orange { - --tw-border-opacity: 1; - border-color: rgb(220 96 22 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(220 96 22 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.btn.orange:hover { - --tw-border-opacity: 1; - border-color: rgb(206 68 12 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(206 68 12 / var(--tw-bg-opacity)); -} - -.btn.white { - border-width: 2px; - --tw-border-opacity: 1; - border-color: rgb(220 96 22 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(220 96 22 / var(--tw-text-opacity)); -} - -.btn.white:hover { - --tw-bg-opacity: 1; - background-color: rgb(220 96 22 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -/* END OF TEMP STYLES */ - .btn-sm { padding-top: 0.125rem; padding-bottom: 0.125rem; @@ -1886,72 +1664,20 @@ main .section { /* START OF CORE STYLES */ -.btn-primary-purple { - --tw-border-opacity: 1; - border-color: rgb(117 35 255 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(117 35 255 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.btn-primary-purple:hover { - --tw-border-opacity: 1; - border-color: rgb(64 0 165 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(64 0 165 / var(--tw-bg-opacity)); -} - -.btn-info { - --tw-border-opacity: 1; - border-color: rgb(59 199 229 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(59 199 229 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.btn-info:hover { - --tw-border-opacity: 1; - border-color: rgb(1 139 157 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(1 139 157 / var(--tw-bg-opacity)); -} - -.btn-outline-trending-brand { - border-width: 2px; - --tw-border-opacity: 1; - border-color: rgb(117 35 255 / var(--tw-border-opacity)); - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(117 35 255 / var(--tw-text-opacity)); -} - -.btn-outline-trending-brand:hover { - --tw-bg-opacity: 1; - background-color: rgb(117 35 255 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -/* END OF CORE STYLES */ - -.outline { - border-width: 2px; +.btn-primary-purple { --tw-border-opacity: 1; - border-color: rgb(243 244 246 / var(--tw-border-opacity)); + border-color: rgb(117 35 255 / var(--tw-border-opacity)); --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + background-color: rgb(117 35 255 / var(--tw-bg-opacity)); --tw-text-opacity: 1; - color: rgb(0 0 0 / var(--tw-text-opacity)); + color: rgb(255 255 255 / var(--tw-text-opacity)); } -.outline:hover { +.btn-primary-purple:hover { + --tw-border-opacity: 1; + border-color: rgb(64 0 165 / var(--tw-border-opacity)); --tw-bg-opacity: 1; - background-color: rgb(229 231 235 / var(--tw-bg-opacity)); - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); + background-color: rgb(64 0 165 / var(--tw-bg-opacity)); } .btn-outline-primary { @@ -1988,6 +1714,23 @@ main .section { color: rgb(255 255 255 / var(--tw-text-opacity)); } +.btn-outline-trending-brand { + border-width: 2px; + --tw-border-opacity: 1; + border-color: rgb(117 35 255 / var(--tw-border-opacity)); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(117 35 255 / var(--tw-text-opacity)); +} + +.btn-outline-trending-brand:hover { + --tw-bg-opacity: 1; + background-color: rgb(117 35 255 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + .sticky-footer { position: fixed; bottom: 0.75rem; @@ -2111,14 +1854,118 @@ main .section { margin-bottom: calc(1rem * var(--tw-space-y-reverse)); } -.category .default-content-wrapper p { +.topic main, .topichub main { + margin-left: auto; + margin-right: auto; + display: grid; + max-width: 80rem; + padding-left: 1rem; + padding-right: 1rem; +} + +@media (min-width: 1024px) { + + .topic main, .topichub main { + grid-template-columns: repeat(4, minmax(0, 1fr)); + padding-left: 0px; + padding-right: 0px; + } +} + +.topic main > div, .topichub main > div { + margin-bottom: 0.5rem; + flex: 1 1 0%; +} + +.topic main > div > :not([hidden]) ~ :not([hidden]), .topichub main > div > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.topic main > div, .topichub main > div { + padding: 0px; + padding-left: 0px; +} + +@media (min-width: 1024px) { + + .topic main > div, .topichub main > div { + grid-column: span 3 / span 3; + grid-column-start: 2; + padding-left: 3rem; + } +} + +.topic main > .side-nav-container, .topichub main > .side-nav-container { + display: none; +} + +@media (min-width: 1024px) { + + .topic main > .side-nav-container, .topichub main > .side-nav-container { + grid-column: span 1 / span 1 !important; + grid-column-start: 1 !important; + grid-row: span 6 / span 6; + display: block; + padding-left: 1.5rem; + } + + .topic main > .side-nav-container + .section, .topichub main > .side-nav-container + .section { + padding-top: 1rem; + } +} + +.\!category main .section { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.category main .section { + padding-top: 2rem; + padding-bottom: 2rem; +} + +@media (min-width: 1280px) { + + .\!category .default-content-wrapper p { + width: 75%; + } + + .category .default-content-wrapper p { + width: 75%; + } +} + +.\!category .default-content-wrapper h2, .\!category .accordion-wrapper h2 { + padding-top: 1rem; + font-size: 1.5rem; + line-height: 2rem; + font-weight: 600; +} + +.category .default-content-wrapper h2, .category .accordion-wrapper h2 { + padding-top: 1rem; + font-size: 1.5rem; + line-height: 2rem; + font-weight: 600; +} + +.\!category .default-content-wrapper h2, .\!category .accordion-wrapper h2 { + padding-top: 1rem; + font-size: 1.5rem; + line-height: 2rem; + font-weight: 600; +} + +main .default-content-wrapper p { font-size: 1rem; line-height: 1.75rem; --tw-text-opacity: 1; color: rgb(55 65 81 / var(--tw-text-opacity)); } -.category .default-content-wrapper p a { +main .default-content-wrapper p a { position: relative; z-index: 0; word-break: break-all; @@ -2127,7 +1974,7 @@ main .section { text-decoration-thickness: 3px; } -.category .default-content-wrapper p a:hover { +main .default-content-wrapper p a:hover { --tw-bg-opacity: 1; background-color: rgb(59 199 229 / var(--tw-bg-opacity)); --tw-text-opacity: 1; @@ -2139,25 +1986,81 @@ main .section { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } -@media (min-width: 1280px) { +main .default-content-wrapper p.button-container>a { + margin-top: 1.5rem; + border-radius: 9999px; + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(117 35 255 / var(--tw-border-opacity)); + background-color: transparent; + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: 1.125rem; + font-weight: 500; + line-height: 1.25rem; + --tw-text-opacity: 1; + color: rgb(117 35 255 / var(--tw-text-opacity)); + text-decoration-line: none; + transition-property: all; + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} - .category .default-content-wrapper p { - width: 75%; - } +main .default-content-wrapper p.button-container>a:hover { + --tw-bg-opacity: 1; + background-color: rgb(117 35 255 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); } -.category .default-content-wrapper h2 { - padding-top: 1rem; - font-size: 1.5rem; - line-height: 2rem; - font-weight: 600; +main .default-content-wrapper p:not(img) { + margin-top: 1rem; + margin-bottom: 1.5rem; +} + +main .default-content-wrapper ol, main .default-content-wrapper ul { + margin-top: 0.75rem; + margin-left: 3rem; + list-style-position: outside; + font-size: 1rem; + line-height: 1.75rem; --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); + color: rgb(55 65 81 / var(--tw-text-opacity)); } -.category main .section { - padding-top: 2rem; - padding-bottom: 2rem; +main .default-content-wrapper ol a, main .default-content-wrapper ul a { + position: relative; + z-index: 0; + word-break: break-all; + text-decoration-line: underline; + text-decoration-color: #3bc7e5; + text-decoration-thickness: 3px; +} + +main .default-content-wrapper ol a:hover, main .default-content-wrapper ul a:hover { + --tw-bg-opacity: 1; + background-color: rgb(59 199 229 / var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +main .default-content-wrapper ol>li, main .default-content-wrapper ul>li { + margin-bottom: 0.25rem; +} + +main .default-content-wrapper ol { + list-style-type: decimal; +} + +main .default-content-wrapper ul { + list-style-type: disc; } .sr-only { @@ -2350,10 +2253,18 @@ main .section { margin-bottom: 3rem; } +.mb-16 { + margin-bottom: 4rem; +} + .mb-2 { margin-bottom: 0.5rem; } +.mb-20 { + margin-bottom: 5rem; +} + .mb-3 { margin-bottom: 0.75rem; } @@ -2366,6 +2277,10 @@ main .section { margin-bottom: 1.25rem; } +.mb-8 { + margin-bottom: 2rem; +} + .mb-\[2px\] { margin-bottom: 2px; } @@ -2499,6 +2414,10 @@ main .section { height: 5rem !important; } +.h-1 { + height: 0.25rem; +} + .h-10 { height: 2.5rem; } @@ -2519,6 +2438,10 @@ main .section { height: 0.5rem; } +.h-20 { + height: 5rem; +} + .h-24 { height: 6rem; } @@ -2677,6 +2600,10 @@ main .section { min-width: 320px; } +.min-w-\[40\%\] { + min-width: 40%; +} + .\!max-w-\[unset\] { max-width: unset !important; } @@ -2737,6 +2664,10 @@ main .section { flex-basis: 50%; } +.table-auto { + table-layout: auto; +} + .-translate-x-8 { --tw-translate-x: -2rem; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -2854,6 +2785,10 @@ main .section { gap: 0.5rem; } +.gap-3 { + gap: 0.75rem; +} + .gap-4 { gap: 1rem; } @@ -2948,6 +2883,11 @@ main .section { border-color: rgb(117 35 255 / var(--tw-divide-opacity)); } +.divide-gray-200 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-divide-opacity)); +} + .divide-gray-900\/10 > :not([hidden]) ~ :not([hidden]) { border-color: rgb(17 24 39 / 0.1); } @@ -3051,6 +2991,10 @@ main .section { border-top-width: 2px; } +.border-t-8 { + border-top-width: 8px; +} + .border-danaherpurple-500 { --tw-border-opacity: 1; border-color: rgb(117 35 255 / var(--tw-border-opacity)); @@ -3085,6 +3029,11 @@ main .section { border-color: transparent; } +.border-b-gray-200 { + --tw-border-opacity: 1; + border-bottom-color: rgb(229 231 235 / var(--tw-border-opacity)); +} + .\!bg-transparent { background-color: transparent !important; } @@ -3277,6 +3226,11 @@ main .section { padding-right: 1rem; } +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + .px-6 { padding-left: 1.5rem; padding-right: 1.5rem; @@ -3342,6 +3296,11 @@ main .section { padding-bottom: 2rem; } +.py-9 { + padding-top: 2.25rem; + padding-bottom: 2.25rem; +} + .\!pb-0 { padding-bottom: 0px !important; } @@ -3557,6 +3516,10 @@ main .section { line-height: 1.75rem; } +.leading-8 { + line-height: 2rem; +} + .leading-none { line-height: 1; } @@ -3683,6 +3646,10 @@ main .section { color: rgb(255 255 255 / var(--tw-text-opacity)); } +.\!no-underline { + text-decoration-line: none !important; +} + .opacity-50 { opacity: 0.5; } @@ -3840,6 +3807,10 @@ main .section { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } +.hover\:rounded-md:hover { + border-radius: 0.375rem; +} + .hover\:border-t-2:hover { border-top-width: 2px; } @@ -3859,6 +3830,11 @@ main .section { background-color: rgb(59 199 229 / var(--tw-bg-opacity)); } +.hover\:bg-danaherpurple-25:hover { + --tw-bg-opacity: 1; + background-color: rgb(245 239 255 / var(--tw-bg-opacity)); +} + .hover\:bg-danaherpurple-50:hover { --tw-bg-opacity: 1; background-color: rgb(234 222 255 / var(--tw-bg-opacity)); @@ -4053,10 +4029,18 @@ main .section { height: 100%; } + .md\:w-1\/4 { + width: 25%; + } + .md\:w-20 { width: 5rem; } + .md\:w-3\/4 { + width: 75%; + } + .md\:w-3\/5 { width: 60%; } @@ -4073,6 +4057,10 @@ main .section { width: 100%; } + .md\:min-w-\[20\%\] { + min-width: 20%; + } + .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } @@ -4095,6 +4083,10 @@ main .section { margin-bottom: calc(0px * var(--tw-space-y-reverse)); } + .md\:border-t { + border-top-width: 1px; + } + .md\:p-0 { padding: 0px; } @@ -4108,6 +4100,11 @@ main .section { padding-bottom: 2.5rem !important; } + .md\:px-0 { + padding-left: 0px; + padding-right: 0px; + } + .md\:px-12 { padding-left: 3rem; padding-right: 3rem; @@ -4132,6 +4129,14 @@ main .section { padding-top: 1rem; padding-bottom: 1rem; } + + .md\:pr-8 { + padding-right: 2rem; + } + + .md\:text-right { + text-align: right; + } } @media (min-width: 1024px) { @@ -4238,6 +4243,11 @@ main .section { padding-right: 0px; } + .lg\:px-10 { + padding-left: 2.5rem; + padding-right: 2.5rem; + } + .lg\:px-7 { padding-left: 1.75rem; padding-right: 1.75rem; diff --git a/styles/tailwind.css b/styles/tailwind.css index 5cd5c5f2d..d46d4ca4b 100644 --- a/styles/tailwind.css +++ b/styles/tailwind.css @@ -13,11 +13,11 @@ @import '../blocks/banner/banner.css'; @import '../templates/blog/blog.css'; @import '../templates/topic/topic.css'; +@import '../templates/library/library.css'; @import '../blocks/testimonial/testimonial.css'; @import '../blocks/cards/cards.css'; @import '../blocks/columns/columns.css'; @import '../blocks/header/header.css'; -@import '../blocks/blog-hero/blog-hero.css'; @import '../blocks/social-media/social-media.css'; @import '../blocks/category-family/category-family.css'; @import '../styles/modal/modal.css'; @@ -63,6 +63,14 @@ h6 { @apply font-normal text-base; } + + main .default-content-wrapper h1 { + @apply text-gray-900 font-extrabold text-4xl; + } + + main .default-content-wrapper h2, main .accordion-wrapper h2 { + @apply text-gray-900 font-medium text-3xl; + } } @layer components { @@ -94,16 +102,6 @@ @apply inline-flex justify-center place-items-center py-1.5 px-3 text-white text-base text-center font-normal whitespace-nowrap no-underline align-middle cursor-pointer space-x-1 tracking-wide select-none rounded transition focus:outline-none bg-danaherorange-500 hover:bg-danaherorange-800; } - /* START OF TEMP STYLES */ - .btn.orange { - @apply text-white bg-danaherorange-500 hover:bg-danaherorange-800 border-danaherorange-500 hover:border-danaherorange-800; - } - - .btn.white { - @apply text-danaherorange-500 bg-white border-2 border-danaherorange-500 hover:text-white hover:bg-danaherorange-500; - } - - /* END OF TEMP STYLES */ .btn-sm { @apply py-0.5 text-sm; } @@ -149,55 +147,6 @@ @apply text-danaherorange-500 bg-white border-2 border-danaherorange-500 hover:text-white hover:bg-danaherorange-500; } - .btn-tertiary { - @apply text-white bg-lightblue-500 hover:bg-lightblue-600 border-lightblue-500 hover:border-lightblue-600; - } - - .btn-brand { - @apply text-white bg-danaherorange-500 hover:bg-danaherorange-800 border-danaherorange-500 hover:border-danaherorange-800; - } - - .btn-info { - @apply text-white bg-lightblue-500 hover:bg-lightblue-600 border-lightblue-500 hover:border-lightblue-600; - } - - .btn-trending-brand { - @apply text-white bg-danaherpurple-500 hover:bg-danaherpurple-800 border-danaherpurple-500; - } - - .btn-outline-brand { - @apply text-danaherorange-500 bg-white border-2 border-danaherorange-500 hover:text-white hover:bg-danaherorange-500; - } - - .btn-outline-trending-brand { - @apply text-danaherpurple-500 bg-white border-2 border-danaherpurple-500 hover:text-white hover:bg-danaherpurple-500; - } - - /* END OF CORE STYLES */ - .btn-dialog { - @apply text-white bg-salmon-500 hover:bg-salmon-700 focus:ring-salmon-700; - } - - .btn-success { - @apply text-white bg-green-500 hover:bg-green-600 focus:ring-green-600; - } - - .btn-danger { - @apply text-white bg-red-500 hover:bg-red-600 focus:ring-red-600; - } - - .btn-warning { - @apply text-white bg-yellow-500 hover:bg-yellow-600 focus:ring-yellow-600; - } - - .outline { - @apply text-black bg-white border-2 border-gray-100 hover:text-white hover:bg-gray-200; - } - - .btn-outline-dialog { - @apply text-salmon-500 bg-white border-2 border-salmon-500 hover:text-white hover:bg-salmon-500; - } - .btn-outline-primary { @apply text-blue-500 bg-white border-2 border-blue-500 hover:text-white hover:bg-blue-500; } @@ -206,28 +155,8 @@ @apply text-gray-500 bg-white border-2 border-gray-500 hover:text-white hover:bg-gray-500; } - .btn-outline-success { - @apply text-green-500 bg-white border-2 border-green-500 hover:text-white hover:bg-green-500; - } - - .btn-outline-danger { - @apply text-red-500 bg-white border-2 border-red-500 hover:text-white hover:bg-red-500 focus:ring-red-500; - } - - .btn-outline-warning { - @apply text-yellow-500 bg-white border-2 border-yellow-500 hover:text-white hover:bg-yellow-500 focus:ring-yellow-500; - } - - .btn-outline-info { - @apply text-lightblue-500 bg-white border-2 border-lightblue-500 hover:text-white hover:bg-lightblue-500 focus:ring-lightblue-500; - } - - .btn-primary-brand { - @apply text-white bg-danaherblue-600 focus:ring-danaherblue-600 hover:bg-danaherorange-500; - } - - .btn-transparent { - @apply text-white bg-transparent border border-white focus:ring-white px-10 py-5 text-xl hover:bg-white hover:text-black; + .btn-outline-trending-brand { + @apply text-danaherpurple-500 bg-white border-2 border-danaherpurple-500 hover:text-white hover:bg-danaherpurple-500; } .form-input, @@ -303,17 +232,65 @@ @apply list-disc list-outside ml-12 mb-4 space-y-4; } - .category .default-content-wrapper p { - @apply xl:w-3/4 leading-7 href-text text-base text-danahergray-700; + .topic main, .topichub main { + @apply grid px-4 lg:px-0 max-w-7xl mx-auto lg:grid-cols-4 } - .category .default-content-wrapper h2 { - @apply font-semibold text-2xl text-danahergray-900 pt-4; + .topic main > div, .topichub main > div { + @apply lg:col-span-3 lg:col-start-2 space-y-4 mb-2 flex-1 p-0 pl-0 lg:pl-12 } - + + .topic main > .side-nav-container, .topichub main > .side-nav-container { + @apply hidden lg:block lg:!col-span-1 lg:!col-start-1 lg:row-span-6 lg:pl-6 + } + + .topic main > .side-nav-container + .section, .topichub main > .side-nav-container + .section { + @apply lg:pt-4 + } + .category main .section { @apply py-8; } + + .category .default-content-wrapper p { + @apply xl:w-3/4; + } + + .category .default-content-wrapper h2, .category .accordion-wrapper h2 { + @apply font-semibold text-2xl pt-4; + } + + main .default-content-wrapper p { + @apply leading-7 href-text text-base text-danahergray-700; + } + + main .default-content-wrapper p.button-container>a { + @apply bg-transparent no-underline text-lg px-5 py-3 text-danaherpurple-500 border border-danaherpurple-500 leading-5 rounded-full font-medium mt-6 ease-in-out duration-150 transition-all; + } + + main .default-content-wrapper p.button-container>a:hover { + @apply bg-danaherpurple-500 text-white; + } + + main .default-content-wrapper p:not(img) { + @apply mt-4 mb-6; + } + + main .default-content-wrapper ol, main .default-content-wrapper ul { + @apply mt-3 leading-7 href-text text-base text-danahergray-700 ml-12 list-outside; + } + + main .default-content-wrapper ol>li, main .default-content-wrapper ul>li { + @apply mb-1 + } + + main .default-content-wrapper ol { + @apply list-decimal; + } + + main .default-content-wrapper ul { + @apply list-disc; + } } @layer utilities { diff --git a/templates/blog/blog.css b/templates/blog/blog.css index c543b4918..6ba3f30f5 100644 --- a/templates/blog/blog.css +++ b/templates/blog/blog.css @@ -2,66 +2,26 @@ @apply mx-auto max-w-7xl flex flex-row gap-10 max-w-7xl mx-auto w-full bg-white; } -.blog main .section{ - @apply py-10 sm:py-8 md:px-5; +.blog main .section { + @apply py-10 sm:py-8 md:px-5 empty:hidden; } .blog main .default-content-wrapper h1:first-child { - @apply text-gray-900 font-extrabold text-4xl mt-0 mb-2; -} - -.blog main .default-content-wrapper p:not(:first-of-type) { - @apply mt-3 leading-7 text-base text-danahergray-700; -} - -.blog main .default-content-wrapper img:first-child { - @apply mt-2 mb-4; -} - -.blog main .default-content-wrapper h2 { - @apply inline-flex font-semibold text-xl text-danahergray-900; + @apply mt-0 mb-2; } .blog main p { - @apply mt-3 leading-7 href-text text-base text-danahergray-700; + @apply mt-3; } -.blog main .default-content-wrapper p{ +.blog main .default-content-wrapper > * { @apply !px-2; } -.blog main h2 { - @apply inline-flex font-semibold text-xl text-danahergray-900; -} - -.blog main a { - @apply font-semibold; -} - -.blog main p.button-container>a { - @apply bg-transparent no-underline text-lg px-5 py-3 text-danaherpurple-500 border border-danaherpurple-500 leading-5 rounded-full font-medium mt-6 ease-in-out duration-150 transition-all; -} - -.blog main p.button-container>a:hover { - @apply bg-danaherpurple-500 text-white; -} - -.blog main .default-content-wrapper ol, .blog main .default-content-wrapper ul { - @apply mt-3 leading-7 href-text text-base text-danahergray-700 ml-12 list-outside; -} - -.blog main .default-content-wrapper ol>li, .blog main .default-content-wrapper ul>li { - @apply mb-1 -} - -.blog main .default-content-wrapper ol { - @apply list-decimal; -} - -.blog main .default-content-wrapper ul { - @apply list-disc; -} - .blog main .popular-articles { @apply lg:w-96 hidden lg:block flex-shrink-0 py-10 bg-danaherlightblue-50; +} + +.blog main .table { + @apply py-6 } \ No newline at end of file diff --git a/templates/blog/blog.js b/templates/blog/blog.js index f5832433d..f9739370a 100644 --- a/templates/blog/blog.js +++ b/templates/blog/blog.js @@ -42,12 +42,12 @@ function buildJsonLd() { export default async function buildAutoBlocks() { const main = document.querySelector('main'); main.classList.add('mx-auto', 'max-w-7xl', 'flex', 'flex-row', 'gap-8', 'max-w-7xl', 'mx-auto', 'w-full', 'bg-white'); - const mainWrapper = main.querySelector(':scope > div'); + const mainWrapper = main.querySelector(':scope > div:nth-child(2)'); let blogH1 = ''; let blogHeroP1 = ''; let blogHeroP2 = ''; - const firstThreeChildren = Array.from(mainWrapper.children).slice(1, 4); + const firstThreeChildren = Array.from(mainWrapper.children).slice(0, 3); firstThreeChildren.every((child) => { if (child.tagName === 'H1' && !blogH1) { blogH1 = child; diff --git a/templates/library/library.css b/templates/library/library.css new file mode 100644 index 000000000..62c26a803 --- /dev/null +++ b/templates/library/library.css @@ -0,0 +1,11 @@ +.library main { + @apply mx-auto max-w-7xl flex flex-row gap-10 max-w-7xl mx-auto w-full bg-white; +} + +.library main .section { + @apply pl-0; +} + +.library main .section .call-to-action-wrapper h2 { + @apply !text-2xl p-0 m-0 tracking-tight sm:text-3xl text-white font-normal tracking-wide; +} \ No newline at end of file diff --git a/templates/library/library.js b/templates/library/library.js new file mode 100644 index 000000000..e69de29bb diff --git a/templates/topic/topic.css b/templates/topic/topic.css index 76a5b67c9..5b5717909 100644 --- a/templates/topic/topic.css +++ b/templates/topic/topic.css @@ -1,29 +1,9 @@ -.topic main { - @apply flex flex-col px-4 lg:px-0 max-w-7xl mx-auto; -} - -.topic main .section { - @apply lg:w-3/4 flex-1 lg:ml-auto p-0 pl-0 lg:pl-6; -} - .topic main .button-container a { @apply btn-outline-trending-brand text-lg px-6 py-2.5 my-8 rounded-full; } -.topic main > div:first-child { - @apply space-y-4 mb-2; -} - -.topic main > div:first-child .default-content-wrapper h1 { - @apply text-gray-900 my-2 font-extrabold text-4xl py-2 px-0; -} - -.product-topic-takeaway .default-content-wrapper { - @apply mb-20 bg-danaherpurple-50 border-t-8 border-danaherpurple-500 px-6 lg:px-10 py-6 space-y-4 leading-7 text-base text-danahergray-700; -} - -*:has(.product-topic-takeaway) .default-content-wrapper h2 { - @apply text-xl font-semibold text-danahergray-900 my-0; +.topic main .default-content-wrapper h1 { + @apply my-2 py-2 px-0; } .topic main p:not(.show-modal-btn) { @@ -36,4 +16,4 @@ .topic main img { @apply w-full mt-10 mb-4; -} \ No newline at end of file +} diff --git a/templates/topic/topic.js b/templates/topic/topic.js index bf171bd04..bb11f11bf 100644 --- a/templates/topic/topic.js +++ b/templates/topic/topic.js @@ -1,16 +1,11 @@ +import { div } from '../../scripts/dom-builder.js'; import { buildBlock } from '../../scripts/lib-franklin.js'; -export default async function buildAutoBlocks(block) { - block.querySelectorAll('h2')?.forEach((element) => { - element.classList.add('font-semibold', 'text-xl', 'text-danahergray-900'); - }); +export default async function buildAutoBlocks() { const main = document.querySelector('main'); - const firstWrapper = main.querySelector(':scope > div'); - firstWrapper.prepend( - buildBlock('social-media', { elems: [] }), - ); - const lastWrapper = main.querySelector(':scope > div:last-of-type'); - lastWrapper.append( - buildBlock('social-media', { elems: [] }), - ); + const sideNavBlock = div(buildBlock('side-nav', { elems: [] })); + sideNavBlock.querySelector('.side-nav').classList.add('topics'); + main.firstElementChild.insertAdjacentElement('afterend', sideNavBlock); + main.querySelector(':scope > div:nth-child(3)')?.prepend(buildBlock('social-media', { elems: [] })); + main.lastElementChild.append(buildBlock('social-media', { elems: [] })); } diff --git a/tools/actions/convert/test/converter.test.js b/tools/actions/convert/test/converter.test.js index 059806f73..c8056f49c 100644 --- a/tools/actions/convert/test/converter.test.js +++ b/tools/actions/convert/test/converter.test.js @@ -85,4 +85,13 @@ describe('Converter Tests', () => { it('convert the topic hub html', async () => { await test('topic-hub'); }); + it('convert the library hub html', async () => { + await test('library-hub'); + }); + it('convert the library html', async () => { + await test('library'); + }); + it('convert the application html', async () => { + await test('application'); + }); }); diff --git a/tools/actions/convert/test/fixtures/application-semantic.html b/tools/actions/convert/test/fixtures/application-semantic.html new file mode 100644 index 000000000..5791555f4 --- /dev/null +++ b/tools/actions/convert/test/fixtures/application-semantic.html @@ -0,0 +1,61 @@ + + + +
+
+
+ +
+ +
+
+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/application.html b/tools/actions/convert/test/fixtures/application.html new file mode 100644 index 000000000..8499be9bb --- /dev/null +++ b/tools/actions/convert/test/fixtures/application.html @@ -0,0 +1,798 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Applications | Danaher Life Sciences + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + + + + +
+
+ + + + +
+ +
+ + + + +
+ + + +
+ +
+ +
+ +
+
+
+
+
+ + + + + + + + + +
+ + +
+ + +
+ + + + + + + + +
+
+ + + + + + + + +
+
+ +

+

+

+ +
+ + + +
+ + +
+
+ + + + + +
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/blog-hub-semantic.html b/tools/actions/convert/test/fixtures/blog-hub-semantic.html index f1439283a..0c0bb82f7 100644 --- a/tools/actions/convert/test/fixtures/blog-hub-semantic.html +++ b/tools/actions/convert/test/fixtures/blog-hub-semantic.html @@ -13,6 +13,7 @@ +
+

The AI-powered pixel classifier

Fast and reproducible microscopy-image segmentation results

+
+
+
+

Key Takeaway Text Example:

+

The most important thing to consider for your experiment is keeping your sample alive and healthy during sample preparation and imaging. Thus, it is critical to maintain the sample in an environment that resembles as closely as possible physiological conditions, i.e., temperature, pH, oxygen levels, and other important factors.

+
+
+

Quantitative analysis of a sample’s microstructure is based on image segmentation, but dividing the image into constituent objects of interest and their local background is a challenge for scientists. Classical function-based automation has its limits for classifying images. Achieving reproducible results manually requires expertise and is tedious work. But now there is a way to overcome these challenges by speeding up this analysis to extract the real value of the image and gain insights. The artificial-intelligence-powered pixel classifier provides reproducible segmentation results fast and overcomes human action. It delivers more robust results compared to classical function-based automation. And here is why …

The original article was published by Leica Microsystems.


@@ -39,6 +49,10 @@

The AI-powered pixel classifier

keywords
Data Science & Deep Learning,Automation
+
+
Tags
+
danaher:topics/data science-deep learning,danaher:topics/automation
+
Description
The artificial-intelligence-powered pixel classifier provides reproducible segmentation results fast and overcomes human action.
@@ -65,11 +79,11 @@

The AI-powered pixel classifier

creationDate
-
+
Fri, 16 Dec 2022 10:55:52 GMT
updateDate
-
+
Thu, 16 Nov 2023 19:20:13 GMT
diff --git a/tools/actions/convert/test/fixtures/blog.html b/tools/actions/convert/test/fixtures/blog.html index e5479ae28..b9a30df44 100644 --- a/tools/actions/convert/test/fixtures/blog.html +++ b/tools/actions/convert/test/fixtures/blog.html @@ -7,7 +7,9 @@ - + + + @@ -36,7 +38,9 @@ - + + + The AI-powered pixel classifier | Danaher Life Sciences @@ -47,8 +51,30 @@ + + + + + + + + + - + + + + + + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/blog2-semantic.html b/tools/actions/convert/test/fixtures/blog2-semantic.html index 332e2e81d..846935c1a 100644 --- a/tools/actions/convert/test/fixtures/blog2-semantic.html +++ b/tools/actions/convert/test/fixtures/blog2-semantic.html @@ -14,9 +14,10 @@ +

9 Essential Products for Streamlining Your mRNA Development and Manufacturing

- null +

In the realm of life sciences, the tools you employ can significantly influence your work's efficiency and outcomes. For scientists, lab managers, and lab directors involved in mRNA development and manufacturing, having the right instruments at your fingertips can be a game-changer. Here, we spotlight nine indispensable products from Danaher Life Science companies that are revolutionizing this field.

@@ -32,7 +33,7 @@

1. Biomek i7 Automated Liquid Handlers

- null +

@@ -47,7 +48,7 @@

2. Echo 525 Acoustic Liquid Handlers

- null +

@@ -62,7 +63,7 @@

3. Intabio ZT System

- null +

@@ -77,7 +78,7 @@

4. IDBS Polar

- null +

@@ -92,7 +93,7 @@

5. Biophase 8800 Capillary Electrophoresis Systems

- null +

@@ -107,7 +108,7 @@

6. SpectraMax Microplate Readers

- null +

@@ -122,7 +123,7 @@

7. ZenoTOF 7600 Mass Spectrometer

- null +

@@ -137,7 +138,7 @@

8. BioZen Oligo Analytical HPLC Columns

- null +

diff --git a/tools/actions/convert/test/fixtures/blog2.html b/tools/actions/convert/test/fixtures/blog2.html index a90bc3fb7..9de83d346 100644 --- a/tools/actions/convert/test/fixtures/blog2.html +++ b/tools/actions/convert/test/fixtures/blog2.html @@ -41,88 +41,6 @@ - - - - - Essential Tools for Streamlining mRNA Development | Danaher Life Sciences @@ -148,75 +66,6 @@ - - - - - - - - - - - - - @@ -531,7 +380,7 @@
- +
@@ -623,7 +472,7 @@
- +
@@ -695,7 +544,7 @@
- +
@@ -767,7 +616,7 @@
- +
@@ -839,7 +688,7 @@
- +
@@ -911,7 +760,7 @@
- +
@@ -983,7 +832,7 @@
- +
@@ -1055,7 +904,7 @@
- +
@@ -1127,7 +976,7 @@
- +
diff --git a/tools/actions/convert/test/fixtures/blog3-semantic.html b/tools/actions/convert/test/fixtures/blog3-semantic.html index 187c7a365..2acffb32f 100644 --- a/tools/actions/convert/test/fixtures/blog3-semantic.html +++ b/tools/actions/convert/test/fixtures/blog3-semantic.html @@ -14,6 +14,7 @@
+

Enabling Science at Scale: How Danaher Life Sciences partners deep with Biopharma

Video Player

The demand for advanced therapeutics and new drug modalities is expected to explode in the coming decade. For example, more than 2,000 gene therapies and modified cell therapies are currently under development, along with 800-plus non-genetically modified cell therapies, according to the American Society of Gene & Cell Therapy. And the development pipeline for monoclonal antibodies grew about 20% in 2022 to include 140 investigational drugs, estimates the Antibody Society.

diff --git a/tools/actions/convert/test/fixtures/blog3.html b/tools/actions/convert/test/fixtures/blog3.html index 01c32e287..f14be01e7 100644 --- a/tools/actions/convert/test/fixtures/blog3.html +++ b/tools/actions/convert/test/fixtures/blog3.html @@ -41,88 +41,6 @@ - - - - - Enabling Science at Scale: How Danaher Life Sciences partners deep with Biopharma | Danaher Life Sciences @@ -148,75 +66,6 @@ - - - - - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/blog4-semantic.html b/tools/actions/convert/test/fixtures/blog4-semantic.html index 8ac442cab..26cca6cef 100644 --- a/tools/actions/convert/test/fixtures/blog4-semantic.html +++ b/tools/actions/convert/test/fixtures/blog4-semantic.html @@ -14,6 +14,7 @@ +

How organoids can redefine pre-clinical research

Organoids, lab-grown 3D structures that mimic human organs, are redefining preclinical research through bypassing the ethical and practical limitations of animal models. Technological advancements in organoid research, including automation and improved analytical tools, promise to unlock new possibilities by streamlining the application of these 3D structures to enhance drug development and disease modelling.

diff --git a/tools/actions/convert/test/fixtures/blog4.html b/tools/actions/convert/test/fixtures/blog4.html index eb5fa2297..9b4eafda1 100644 --- a/tools/actions/convert/test/fixtures/blog4.html +++ b/tools/actions/convert/test/fixtures/blog4.html @@ -41,89 +41,6 @@ - - - - - - How organoids can redefine pre-clinical research | Danaher Life Sciences @@ -148,75 +65,6 @@ - - - - - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/blog5-semantic.html b/tools/actions/convert/test/fixtures/blog5-semantic.html index 3c5828ea2..e395633a1 100644 --- a/tools/actions/convert/test/fixtures/blog5-semantic.html +++ b/tools/actions/convert/test/fixtures/blog5-semantic.html @@ -14,6 +14,7 @@ +


The Transformative Power of Insights in Biopharma Development: Why a Digital Backbone Matters

Discover how a digital backbone can help to realize the full potential of data and generate meaningful insights.

Digitalization underpins the biopharma industry’s endeavors to keep up with scientific and technological innovation and to ultimately get life-changing therapeutics into the hands of patients as quickly as possible. However, many have failed to leverage the capabilities of digital and analytics tools, setting them behind on their digital maturation journey and impacting the delivery of therapeutics to market. Biopharma executives are realizing that they now need to “adopt digital technologies faster to win in the market”.1

diff --git a/tools/actions/convert/test/fixtures/blog6-semantic.html b/tools/actions/convert/test/fixtures/blog6-semantic.html index b492268f3..5ec1b37aa 100644 --- a/tools/actions/convert/test/fixtures/blog6-semantic.html +++ b/tools/actions/convert/test/fixtures/blog6-semantic.html @@ -14,6 +14,7 @@ +

The Transformative Power of Insights in Biopharma Development: Why a Digital Backbone Matters

Discover how a digital backbone can help to realize the full potential of data and generate meaningful insights.

@@ -27,6 +28,14 @@

A myriad of experiments, instruments and reports

Key Development Stages

+
+
+
+

Key Takeaway Text Example:

+

The most important thing to consider for your experiment is keeping your sample alive and healthy during sample preparation and imaging. Thus, it is critical to maintain the sample in an environment that resembles as closely as possible physiological conditions, i.e., temperature, pH, oxygen levels, and other important factors.

+
+
+

Figure1: From laboratory to patient - key development stages and their associated documentation required to take a drug to market. Credit:Courtesy ofIDBS.

When reviewing even just the pharmaceutical development section of the IND document (Section 3.2.P.2 Pharmaceutical Development),³the number of systems, instruments, experiments and reports (Table 1) that come together to demonstrate the effectiveness of the process development (PD) stage of drug development cannot be underestimated.

Table1: Non-exhaustive list of example reports compiled within the process development of biological therapeutics.

diff --git a/tools/actions/convert/test/fixtures/blog6.html b/tools/actions/convert/test/fixtures/blog6.html index 2e0499628..be54097c4 100644 --- a/tools/actions/convert/test/fixtures/blog6.html +++ b/tools/actions/convert/test/fixtures/blog6.html @@ -379,6 +379,34 @@ +
+ + + +
+
+
+
+
+ + + + + + +
+ + + +
+ + +
+
+
+
+
diff --git a/tools/actions/convert/test/fixtures/en.html b/tools/actions/convert/test/fixtures/en.html index f4bc44511..fa72bd40f 100644 --- a/tools/actions/convert/test/fixtures/en.html +++ b/tools/actions/convert/test/fixtures/en.html @@ -54,61 +54,6 @@ - - - @@ -126,71 +71,6 @@ - - - - - - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/library-hub-semantic.html b/tools/actions/convert/test/fixtures/library-hub-semantic.html new file mode 100644 index 000000000..9edacc878 --- /dev/null +++ b/tools/actions/convert/test/fixtures/library-hub-semantic.html @@ -0,0 +1,61 @@ + + + +
+
+
+ +
+ +
+
+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/library-hub.html b/tools/actions/convert/test/fixtures/library-hub.html new file mode 100644 index 000000000..5c114628c --- /dev/null +++ b/tools/actions/convert/test/fixtures/library-hub.html @@ -0,0 +1,2854 @@ + + + + + + + + + + + + + + + + + + + + + Knowledge Library Hub | Danaher Life Sciences + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + + + + +
+
+ + + + +
+ +
+ + + + +
+ + + +
+ +
+ +
+ +
+
+
+
+
+ + + + + + + + + +
+ + +
+ + +
+


+

A

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + + + +
+


+

C

+

+
+ + + + +
+ + + + + + + + +
+ + + + +
+


+

C

+

+
+ + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

C

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + + + +
+


+

G

+

+
+ + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

G

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

G

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

G

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

G

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + + + +
+


+

G

+

+
+ + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

O

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

O

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

O

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

O

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + + + +
+


+

O

+

+
+ + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

O

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

O

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

P

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + + + +
+


+

S

+

+
+ + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

S

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

S

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + + + +
+


+

S

+

+
+ + + + +
+ + + + + + + + +
+ + + + +
+


+

S

+

+
+ + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+ +

+

+ +
+ + + +
+
+


+

S

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+
+


+

S

+

+
+
+ + + + + +
+
+ + + + + + +
+ + + + + + + + +
+ + +
+
+ +
+ + +
+
+ + + + + +
+ + + + + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/library-semantic.html b/tools/actions/convert/test/fixtures/library-semantic.html new file mode 100644 index 000000000..d47d84066 --- /dev/null +++ b/tools/actions/convert/test/fixtures/library-semantic.html @@ -0,0 +1,117 @@ + + + +
+
+
+ +
+ +

Cell viability is the measurement of the number of live cells in a sample, typically given as a proportion of the total cell population. It is a critical parameter to measure when assessing the health of any cell culture or outcome of an assay (e.g., transfection).

+

Cell count assays are applicable for every cell type and culture condition, including cell suspensions and adherent cells. During initial seeding or passaging, it is important to plate the correct number of live cells per area or volume for adherent cultures or bioreactors. Large numbers of dead cells can be detrimental to growth as they release proteins and other cellular factors like cytokines that negatively affect viable cells.

+

Cell viability assays represent a crucial testing component during the drug development process. These assays can inform on the effectiveness and toxicity of medications, such as anticancer medications, where cell survival is monitored.

+

Common Cell Viability Assays

+ +
+
+
+

See how Danaher Life Sciences can help

+

Talk to an expert

+
+
+
+

Factors Influencing Cell Viability

+ +

Strategies for Improving Cell Viability

+

Maintaining optimal culture conditions and utilizing cell viability, cell toxicity and cell cycle assays are essential for assessing and enhancing cell viability in various research settings. Optimizing factors such as temperature, pH, nutrient availability and oxygen levels are crucial for maintaining cell viability in cell culture. Proper culture conditions provide cells with the necessary resources for growth and survival. Supplementing the culture medium with cell viability-enhancing compounds like growth factors and antiapoptotic molecules can support cell growth and improve viability. Protective agents can shield cells from harsh conditions and prevent cell death, while antioxidants can mitigate oxidative stress. Additionally, genetic modifications can be employed to enhance cell survival. For example, inhibiting specific genes has been shown to improve cell viability and enhance the expression of key survival genes in certain cancer cells.

+
+
+
+

FAQs

+
+
+
+
+

What is cell viability, and how is it measured?

+

Cell viability is defined as the ability of cells to survive and maintain their physiological functions. It is typically measured by assessing the percentage of live cells in a population using various cell viability assays. The formula to calculate cell viability is (Number of viable cells / Total number of cells) x 100%.

+
+
+
+
+

What is the significance of maintaining cell viability in cell culture?

+

Maintaining cell viability in cell culture is significant for obtaining reliable experimental results, supporting cell propagation and expansion, and facilitating accurate drug efficacy and toxicity assessments.

+
+
+
+
+

Why is cell viability analysis important in research and experimental studies?

+

Cell viability analysis is crucial in research and experimental studies as it ensures the reliability and relevance of data, allowing for accurate assessments of cell cycle phases, cellular responses, the evaluation of treatment efficacy, and the development of effective therapeutic strategies.

+
+
+
+
+

What are the indicators of cell viability?

+

Indicators of cell viability include membrane integrity, metabolic activity, DNA accessibility, cell proliferation and cell morphology.

+
+
+
+
+
+
+

See how Danaher Life Sciences can help

+

Talk to an expert

+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/library.html b/tools/actions/convert/test/fixtures/library.html new file mode 100644 index 000000000..cb989e440 --- /dev/null +++ b/tools/actions/convert/test/fixtures/library.html @@ -0,0 +1,753 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cell Viability: Measurement, Assays & Factors Affecting Cell Health | Danaher Life Sciences + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + + + + + +
+
+ + + + +
+ +
+ + + + +
+ + + +
+ +
+ +
+ +
+
+
+
+
+ + + + + + + + + +
+ + +
+ + +
+ + +
+
+
+ + + + + + +
+ + + +
+ + + + +
+ + + +
+ + + + +
+ + + +
+ + + + +
+ + + +
+ + + + +
+ + + +
+ + + + +
+ + +
+ + + + +
+ + + +
+ + +
+
+
+
+ + +
+
+ + + + + +
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/actions/convert/test/fixtures/news-semantic.html b/tools/actions/convert/test/fixtures/news-semantic.html index 50bde82af..1f80ebb6d 100644 --- a/tools/actions/convert/test/fixtures/news-semantic.html +++ b/tools/actions/convert/test/fixtures/news-semantic.html @@ -14,6 +14,7 @@ +

Gene Editing in Organoids: Accounting for Complexity in Drug Discovery

Gene Editing in Organoids diff --git a/tools/actions/convert/test/fixtures/news.html b/tools/actions/convert/test/fixtures/news.html index 0465008f3..07ea90ebe 100644 --- a/tools/actions/convert/test/fixtures/news.html +++ b/tools/actions/convert/test/fixtures/news.html @@ -40,90 +40,6 @@ - - - - - - - Drug Discovery World | Danaher Life Sciences @@ -148,75 +64,6 @@ - - - - - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/news2-semantic.html b/tools/actions/convert/test/fixtures/news2-semantic.html index 6ae6e6669..3e643d417 100644 --- a/tools/actions/convert/test/fixtures/news2-semantic.html +++ b/tools/actions/convert/test/fixtures/news2-semantic.html @@ -13,6 +13,7 @@ +


ValitaCell Joins Beckman Coulter Life Sciences

ValitaCell Joins Beckman Coulter Life Sciences diff --git a/tools/actions/convert/test/fixtures/news2.html b/tools/actions/convert/test/fixtures/news2.html index 24ddf621d..6d89010fe 100644 --- a/tools/actions/convert/test/fixtures/news2.html +++ b/tools/actions/convert/test/fixtures/news2.html @@ -40,90 +40,6 @@ - - - - - - - ValitaCell Joins Beckman Coulter Life Sciences | Danaher Life Sciences @@ -148,76 +64,6 @@ - - - - - - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/product-category-semantic.html b/tools/actions/convert/test/fixtures/product-category-semantic.html index 4f3b99e40..0a7ce2cb5 100644 --- a/tools/actions/convert/test/fixtures/product-category-semantic.html +++ b/tools/actions/convert/test/fixtures/product-category-semantic.html @@ -14,6 +14,7 @@ +


+
@@ -97,7 +98,8 @@

What is the principle of Capillary electrophoresis?

Need help designing your solution?

-

Request a Quote

+

Request a Quote

+

Talk to an Expert

diff --git a/tools/actions/convert/test/fixtures/product-category1.html b/tools/actions/convert/test/fixtures/product-category1.html index 2090d830a..f801a4daa 100644 --- a/tools/actions/convert/test/fixtures/product-category1.html +++ b/tools/actions/convert/test/fixtures/product-category1.html @@ -41,89 +41,6 @@ - - - - - - Capillary Electrophoresis Instruments and Systems, Automated | Danaher Life Sciences @@ -148,77 +65,6 @@ - - - - - - - - - - - - - - - @@ -634,7 +480,7 @@

FAQs

- +
diff --git a/tools/actions/convert/test/fixtures/product-semantic.html b/tools/actions/convert/test/fixtures/product-semantic.html index ea3080d0b..fda837b8c 100644 --- a/tools/actions/convert/test/fixtures/product-semantic.html +++ b/tools/actions/convert/test/fixtures/product-semantic.html @@ -14,6 +14,7 @@
+
Request for Quote
diff --git a/tools/actions/convert/test/fixtures/product-topic-semantic.html b/tools/actions/convert/test/fixtures/product-topic-semantic.html index 638e5ab5e..6e4911d05 100644 --- a/tools/actions/convert/test/fixtures/product-topic-semantic.html +++ b/tools/actions/convert/test/fixtures/product-topic-semantic.html @@ -16,17 +16,16 @@
-

How are Assay Kits Installed


-

Key Takeaway Text Example:

-

The most important thing to consider for your experiment is keeping your sample alive and healthy during sample preparation and imaging. Thus, it is critical to maintain the sample in an environment that resembles as closely as possible physiological conditions, i.e., temperature, pH, oxygen levels, and other important factors.

-
+

How are Assay Kits Installed

+
-
style
-
product-topic-takeaway
+
+

Key Takeaway Text Example:

+

The most important thing to consider for your experiment is keeping your sample alive and healthy during sample preparation and imaging. Thus, it is critical to maintain the sample in an environment that resembles as closely as possible physiological conditions, i.e., temperature, pH, oxygen levels, and other important factors.

+
-

The understanding of complex and/or fast cellular dynamics is an important step for exploring biological processes. Therefore, today’s life science research is increasingly focused on dynamic processes like cell migration, morphological changes of cells, organs, or whole animals, and real-time physiological (e.g., changes of intracellular ion composition) events in living specimens. One approach to address these challenging demands is to employ certain optical methods that are collectively called live-cell imaging.

Live-cell imaging provides, in real time, a “snapshot” of a cell’s or organism’s current state in its native environment without introducing artifacts typical of fixation. These capabilities make live-cell imaging a requisite technique for addressing questions in cell biology, cancer research, developmental biology, and neuroscience.

In recent years, substantial advances in electronics, optics, and fluorescent tag technology have made live-cell imaging more versatile and easily accessible for scientists.

@@ -44,7 +43,7 @@

Photoactivation – monitoring gene expression and protein transport

Need help designing your solution?

-

Request a Quote

+

Request a Quote

diff --git a/tools/actions/convert/test/fixtures/product-topic.html b/tools/actions/convert/test/fixtures/product-topic.html index 382b4cbfb..fc81c131b 100644 --- a/tools/actions/convert/test/fixtures/product-topic.html +++ b/tools/actions/convert/test/fixtures/product-topic.html @@ -40,90 +40,6 @@ - - - - - - - What Are Assay Kits @@ -147,76 +63,6 @@ - - - - - - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/product.html b/tools/actions/convert/test/fixtures/product.html index e25da412a..c63e09c76 100644 --- a/tools/actions/convert/test/fixtures/product.html +++ b/tools/actions/convert/test/fixtures/product.html @@ -11,84 +11,6 @@ - - @@ -103,70 +25,6 @@ }]; - - - - - - - - - diff --git a/tools/actions/convert/test/fixtures/topic-hub-semantic.html b/tools/actions/convert/test/fixtures/topic-hub-semantic.html index afb7d0623..be1046cd6 100644 --- a/tools/actions/convert/test/fixtures/topic-hub-semantic.html +++ b/tools/actions/convert/test/fixtures/topic-hub-semantic.html @@ -15,6 +15,13 @@ +
+
+
+
+
+
+

Assay Kits

@@ -25,6 +32,7 @@

Assay Kits

Explore our line of Assay Kits

+

View Products

@@ -43,7 +51,7 @@

Explore our line of Assay Kits

updateDate
-
Tue, 14 Nov 2023 13:52:03 GMT
+
Thu, 16 Nov 2023 17:26:13 GMT
diff --git a/tools/actions/convert/test/fixtures/topic-hub.html b/tools/actions/convert/test/fixtures/topic-hub.html index fd51e1a2e..b82b16a5e 100644 --- a/tools/actions/convert/test/fixtures/topic-hub.html +++ b/tools/actions/convert/test/fixtures/topic-hub.html @@ -7,7 +7,9 @@ - + + + @@ -40,92 +42,6 @@ - - - - - - - Topics @@ -144,82 +60,12 @@ dataLayer = [{ 'user': {"customerID":"","accountType":"guest","marketCode":"","company":"","role":"","city":"","state":"","country":"","postalCode":"","lastVisit":""} },{ - 'page': {"title":"Topics","language":"en","locale":"US","level":"top","type":"webpage","keywords":"","creationDate":"Oct 03, 2023 10:32:18 AM","updateDate":"Nov 14, 2023 01:52:03 PM"} + 'page': {"title":"Topics","language":"en","locale":"US","level":"top","type":"webpage","keywords":"","creationDate":"Oct 03, 2023 10:32:18 AM","updateDate":"Nov 16, 2023 05:26:13 PM"} }]; - - - - - - - - - - - - - - @@ -241,7 +87,7 @@ - + diff --git a/tools/importer/transformers/accordion.js b/tools/importer/transformers/accordion.js index 4eab54fa6..67dd7de2a 100644 --- a/tools/importer/transformers/accordion.js +++ b/tools/importer/transformers/accordion.js @@ -4,24 +4,29 @@ const createAccordion = (main, document) => { const accordion = main.querySelector('accordion'); const cells = [['Accordion']]; if (accordion) { - const accordionHeader = document.createElement('div'); + const accordionHeader = document.createElement('h2'); accordionHeader.textContent = accordion.getAttribute('accordionheader'); - // eslint-disable-next-line no-undef - const accordionLists = JSON.parse(decodeHtmlEntities(accordion.getAttribute('accordionlist'))); - const definitionlists = accordionLists.map((list) => { - const pEl = document.createElement('p'); - pEl.innerHTML = list.description; - const divEl = document.createElement('div'); - const strogEl = document.createElement('h3'); - strogEl.innerHTML = list.title; - divEl.append(strogEl); - divEl.append(pEl); - return [divEl]; - }); - if (accordionHeader.textContent) cells.push([accordionHeader]); - cells.push(...definitionlists); - const block = WebImporter.DOMUtils.createTable(cells, document); - accordion.append(block); + try { + // eslint-disable-next-line no-undef + const accordionLists = JSON.parse(decodeHtmlEntities(accordion.getAttribute('accordionlist'))); + const definitionlists = accordionLists.map((list) => { + const pEl = document.createElement('p'); + pEl.innerHTML = list.description; + const divEl = document.createElement('div'); + const strogEl = document.createElement('h3'); + strogEl.innerHTML = list.title; + divEl.append(strogEl); + divEl.append(pEl); + return [divEl]; + }); + if (accordionHeader.textContent) cells.push([accordionHeader]); + cells.push(...definitionlists); + const block = WebImporter.DOMUtils.createTable(cells, document); + accordion.append(block); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error parsing data layer JSON:', error); + } } }; export default createAccordion; diff --git a/tools/importer/transformers/breadcrumb.js b/tools/importer/transformers/breadcrumb.js index 7d8ef1da9..39bef3251 100644 --- a/tools/importer/transformers/breadcrumb.js +++ b/tools/importer/transformers/breadcrumb.js @@ -24,6 +24,7 @@ const createBreadcrumb = (main, document) => { const block = WebImporter.DOMUtils.createTable(cells, document); const firstChild = main.firstElementChild?.firstChild; main.firstElementChild.insertBefore(block, firstChild); + firstChild?.after(document.createElement('hr')); } } } diff --git a/tools/importer/transformers/callToAction.js b/tools/importer/transformers/callToAction.js index c629ae41f..0debfbd61 100644 --- a/tools/importer/transformers/callToAction.js +++ b/tools/importer/transformers/callToAction.js @@ -1,27 +1,52 @@ /* global WebImporter */ -const createCTA = (main, document) => { - const ctaSection = main.querySelector('CTAsection'); +export const c2a = (cta, document) => { + const ctaSection = cta.querySelector('CTAsection'); if (ctaSection) { const title = ctaSection.getAttribute('title'); - const btnText1 = ctaSection.getAttribute('btntext1'); - const rfqBtn1 = ctaSection.getAttribute('rfqbtn1'); const div = document.createElement('div'); const h2 = document.createElement('h2'); h2.textContent = title; if (h2) { div.append(h2); } - const btn = document.createElement('button'); - btn.textContent = btnText1; - if (rfqBtn1 && btn.textContent) { - div.append(btn); + + const btnText1 = ctaSection.getAttribute('btntext1'); + const rfqBtn1 = ctaSection.getAttribute('rfqbtn1'); + const btnhref1 = ctaSection.getAttribute('btnhref1'); + if (btnText1) { + const p1 = document.createElement('p'); + const a1 = document.createElement('a'); + a1.setAttribute('href', rfqBtn1 ? '#request-quote' : btnhref1); + a1.textContent = btnText1; + p1.append(a1); + div.append(p1); + } + + const btnText2 = ctaSection.getAttribute('btntext2'); + const rfqBtn2 = ctaSection.getAttribute('rfqbtn2'); + const btnhref2 = ctaSection.getAttribute('btnhref2'); + if (btnText2) { + const p2 = document.createElement('p'); + const a2 = document.createElement('a'); + a2.setAttribute('href', rfqBtn2 ? '#request-quote' : btnhref2); + a2.textContent = btnText2; + p2.append(a2); + div.append(p2); } const cells = [ - ['call-to-action'], - [div], + ['call-to-action'], [div], ]; const block = WebImporter.DOMUtils.createTable(cells, document); - ctaSection.append(block); + if (ctaSection.closest('div.bg-danaherlightblue-50')) ctaSection.append(document.createElement('hr')); + cta.append(block); } }; + +const createCTA = (main, document) => { + const ctaSection = main.querySelectorAll('div.cta-section'); + [...ctaSection].forEach((cta) => { + c2a(cta, document); + }); +}; + export default createCTA; diff --git a/tools/importer/transformers/cardList.js b/tools/importer/transformers/cardList.js index 73a40188b..a0b23f2c3 100644 --- a/tools/importer/transformers/cardList.js +++ b/tools/importer/transformers/cardList.js @@ -5,7 +5,7 @@ const createCardList = (main, document) => { let blockName; if (url.endsWith('/blog.html')) blockName = 'Card List (blog)'; else if (url.endsWith('/news.html')) blockName = 'Card List (news)'; - else if (url.endsWith('/library.html')) blockName = 'Card List (library)'; + else if (url.endsWith('/application.html')) blockName = 'Card List (application)'; if (blockName) { const block = [[blockName], ['']]; diff --git a/tools/importer/transformers/containerTakeaway.js b/tools/importer/transformers/containerTakeaway.js deleted file mode 100644 index 7964a8c9c..000000000 --- a/tools/importer/transformers/containerTakeaway.js +++ /dev/null @@ -1,25 +0,0 @@ -import { - featureimage, -} from './util.js'; - -/* global WebImporter */ -const createTakeaway = (main, document) => { - main.querySelectorAll('div.container-takeaway').forEach((takeaway) => { - const fulllayout = takeaway?.querySelector('fulllayout'); - const div = fulllayout?.querySelector('div'); - const featureImg = div?.querySelector('div.featureimage'); - if (takeaway) { - takeaway.innerHTML = ''; - const cells = [['Section Metadata'], ['style', 'product-topic-takeaway']]; - const table = WebImporter.DOMUtils.createTable(cells, document); - if (takeaway.previousElementSibling && takeaway.previousElementSibling.className !== 'container-takeaway') { - takeaway.append(document.createElement('hr')); - } - takeaway.append(featureimage(featureImg, document), table); - if (takeaway.nextElementSibling) { - table.after(document.createElement('hr')); - } - } - }); -}; -export default createTakeaway; diff --git a/tools/importer/transformers/index.js b/tools/importer/transformers/index.js index 522988e51..9c78afbd6 100644 --- a/tools/importer/transformers/index.js +++ b/tools/importer/transformers/index.js @@ -26,9 +26,11 @@ import bannerAEM from './bannerAEM.js'; import productCategory from './productCategory.js'; import coveoCategory from './coveoCategory.js'; import workflowContainer from './workflowContainer.js'; -import takeaway from './containerTakeaway.js'; +import takeaway from './takeaway.js'; import topicList from './topicList.js'; import table from './table.js'; +import libraryHub from './libraryHub.js'; +import sideNav from './sideNav.js'; // eslint-disable-next-line import/prefer-default-export export const transformers = [ @@ -59,6 +61,8 @@ export const transformers = [ productCategory, coveoCategory, topicList, + libraryHub, + sideNav, ]; export const xfTransformers = [ diff --git a/tools/importer/transformers/libraryHub.js b/tools/importer/transformers/libraryHub.js new file mode 100644 index 000000000..7b26cd798 --- /dev/null +++ b/tools/importer/transformers/libraryHub.js @@ -0,0 +1,18 @@ +/* global WebImporter */ +const libraryHub = (main, document) => { + const url = document.querySelector('[property="og:url"]')?.content; + if (url?.endsWith('/us/en/library.html') || url?.endsWith('/us/en/info.html')) { + const pageNameMatch = url.match(/\/([^/]+)\.html$/); + if (pageNameMatch) { + const pageName = pageNameMatch[1]; + main.querySelectorAll('div.container-sidebar').forEach((div) => div.remove()); + main + .querySelectorAll('div.aem-Grid.aem-Grid--12.aem-Grid--default--12 h2') + .forEach((h2) => h2.closest('div').remove()); + const block = [[`Card List (${pageName})`], ['']]; + const table = WebImporter.DOMUtils.createTable(block, document); + main.append(table); + } + } +}; +export default libraryHub; diff --git a/tools/importer/transformers/metadata.js b/tools/importer/transformers/metadata.js index 1541cc284..953b819b8 100644 --- a/tools/importer/transformers/metadata.js +++ b/tools/importer/transformers/metadata.js @@ -23,11 +23,27 @@ const addDataLayerMeta = (document, html, meta) => { divEl.innerHTML = html; const scriptElements = Array.from(divEl.querySelectorAll('script')); const filteredScripts = scriptElements.filter((script) => script.textContent.startsWith('\n dataLayer = ')); - const dataLayerJson = filteredScripts[0] ? JSON.parse(filteredScripts[0].textContent.replaceAll('\n', '').replace('dataLayer', '').replace('=', '').replace(';', '') - .replaceAll('\'', '"')) : []; - if (dataLayerJson) { - meta.creationDate = dataLayerJson[1] ? new Date(Date.parse(`${dataLayerJson[1]?.page.creationDate} UTC`)).toUTCString() : ''; - meta.updateDate = dataLayerJson[1] ? new Date(Date.parse(`${dataLayerJson[1]?.page.updateDate} UTC`)).toUTCString() : ''; + try { + const dataLayerJson = filteredScripts[0] ? JSON.parse( + filteredScripts[0].textContent + .replaceAll('\n', '') + .replace('dataLayer', '') + .replace('=', '') + .replace(';', '') + .replace("'user'", '"user"') + .replace("'page'", '"page"'), + ) : []; + if (dataLayerJson) { + meta.creationDate = dataLayerJson[1] + ? new Date(Date.parse(`${dataLayerJson[1]?.page.creationDate} UTC`)).toUTCString() + : ''; + meta.updateDate = dataLayerJson[1] + ? new Date(Date.parse(`${dataLayerJson[1]?.page.updateDate} UTC`)).toUTCString() + : ''; + } + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error parsing data layer JSON:', error); } }; @@ -61,6 +77,11 @@ const createMetadata = (main, document, html, params, url) => { meta.keywords = keywords.content; } + const tags = document.querySelector('[name="tags"]'); + if (tags && tags.content) { + meta.Tags = tags.content; + } + const desc = document.querySelector('[property="og:description"]'); if (desc) { meta.Description = desc.content; diff --git a/tools/importer/transformers/sideNav.js b/tools/importer/transformers/sideNav.js new file mode 100644 index 000000000..af6285241 --- /dev/null +++ b/tools/importer/transformers/sideNav.js @@ -0,0 +1,16 @@ +/* global WebImporter */ +const sideNav = (main, document) => { + const sideNavEl = main.querySelector('#side-nav'); + if (sideNavEl) { + let blockName = 'Side Nav'; + const sideNavContent = sideNavEl?.textContent?.trim(); + if (sideNavContent && sideNavContent.length < 65) { + blockName += ` (${sideNavContent})`; + } + const block = [[blockName], ['']]; + const table = WebImporter.DOMUtils.createTable(block, document); + sideNavEl.replaceWith(table); + table.insertAdjacentElement('afterend', document.createElement('hr')); + } +}; +export default sideNav; diff --git a/tools/importer/transformers/takeaway.js b/tools/importer/transformers/takeaway.js new file mode 100644 index 000000000..dc2166bbd --- /dev/null +++ b/tools/importer/transformers/takeaway.js @@ -0,0 +1,20 @@ +/* global WebImporter */ +import { featureimage } from './util.js'; + +const createTakeaway = (main, document) => { + main.querySelectorAll('div.container-takeaway').forEach((takeaway) => { + const block = [['Takeway']]; + const fullLayout = takeaway?.querySelector('fulllayout'); + const featureImgs = fullLayout?.querySelectorAll('div.featureimage'); + if (featureImgs) { + featureImgs.forEach((featureImg) => { + block.push([featureimage(featureImg, document)]); + }); + } else { + block.push([fullLayout.innerHTML]); + } + const table = WebImporter.DOMUtils.createTable(block, document); + fullLayout.replaceWith(table); + }); +}; +export default createTakeaway; diff --git a/tools/importer/transformers/workflowContainer.js b/tools/importer/transformers/workflowContainer.js index 9a1e1dcf3..396bf9e76 100644 --- a/tools/importer/transformers/workflowContainer.js +++ b/tools/importer/transformers/workflowContainer.js @@ -11,7 +11,10 @@ const createWorkflowContainerSection = (main, document) => { if (i === arr.length - 1) { const cells = [['Section Metadata'], ['style', 'container-two-col']]; const table = WebImporter.DOMUtils.createTable(cells, document); - e.append(table, document.createElement('hr')); + e.append(table); + if (e.nextElementSibling && !e.nextElementSibling.querySelector('div.bg-danaherlightblue-50')) { + e.append(document.createElement('hr')); + } } }); };