From df6edc5ee6d9753db493fc7eeb24a03d916aa4eb Mon Sep 17 00:00:00 2001 From: asthabh23 Date: Tue, 7 Jan 2025 17:57:52 +0530 Subject: [PATCH 1/4] feat: blog list page design --- blocks/feed/feed.css | 125 +++++++++++++++++++++++++++++++++++++------ blocks/feed/feed.js | 104 +++++++++++++++++++++++++++++++++-- scripts/scripts.js | 18 +++++++ 3 files changed, 228 insertions(+), 19 deletions(-) diff --git a/blocks/feed/feed.css b/blocks/feed/feed.css index a68173bbd..dcb141c7d 100644 --- a/blocks/feed/feed.css +++ b/blocks/feed/feed.css @@ -1,8 +1,57 @@ -.feed.recent { +.feed { text-align: left; } -.feed.recent .feed-item img { +.feed-hidden { + display: none; +} + +.feed.blog .blog-link { + text-decoration: none; + color: inherit; +} + +.right-container { + padding-top: 50px; + display: flex; + flex-direction: column; + gap: 20px; +} + +.blog-item:not(.blog-item.latest) { + box-shadow: 0 4px 8px rgba(0 0 0 / 20%); + transition: box-shadow 0.3s ease; + padding: 20px; + background-color: white; +} + +.blog-item:not(.blog-item.latest):hover { + box-shadow: 0 8px 16px rgba(0 0 0 / 40%); +} + +.read-more { + display: inline-block; + margin-top: 10px; + padding: 10px 20px; + border-radius: 25px; + width: 150px; + background-color: var(--spectrum-blue); + color: white; + border: none; + cursor: pointer; + text-align: center; +} + +.read-more:hover { + background-color: var(--dark-spectrum-blue); +} + +.feed.recent .feed-item { + margin: 10px; +} + +.feed.recent .feed-item img, +.blog-container .right-container .blog-item img { max-width: 100%; filter: var(--image-filter-drop-shadow-small); width: 100%; @@ -10,7 +59,8 @@ object-fit: contain; } -.feed.recent > div { +.feed.recent > div, +.feed.blog > div { margin-bottom: var(--spacing-s); padding: var(--spacing-ml) 0; gap: var(--spacing-s); @@ -32,12 +82,28 @@ flex-direction: column; } -.feed.recent .feed-item .image-wrapper-el { +.feed.recent .feed-item .image-wrapper-el, +.feed.blog .blog-item .image-wrapper { margin-top: auto; padding-top: var(--spacing-s); } -.feed.recent h3 { +.feed.blog h1 { + font-size: var(--type-heading-xl-size); + line-height: var(--type-heading-xl-lh); + font-weight: 700; + letter-spacing: -0.04em; +} + +.feed.blog h2 { + font-size: var(--type-heading-l-size); + line-height: var(--type-heading-l-lh); + font-weight: 700; + letter-spacing: -0.04em; +} + +.feed.recent h3, +.feed.blog h3 { margin-bottom: var(--spacing-xs); font-size: var(--type-heading-xl-size); line-height: var(--type-heading-xl-lh); @@ -45,12 +111,14 @@ letter-spacing: -0.04em; } -.feed.recent p { +.feed.recent p, +.feed.blog p { font-size: var(--type-body-s-size); line-height: var(--type-body-s-lh); } -.feed.recent .desc { +.feed.recent .desc, +.feed.blog .desc { /* stylelint-disable-next-line value-no-vendor-prefix */ display: -webkit-box; line-clamp: 5; @@ -61,6 +129,10 @@ } @media screen and (width >= 768px) { + .feed.recent .feed-item { + margin: unset; + } + .feed.recent > div > div { grid-template-columns: 1fr 1fr 1fr; grid-gap: var(--spacing-xs); @@ -71,16 +143,35 @@ text-align: left; } - .feed.recent h3 { + .feed.recent h3, + .feed.blog h3 { font-size: var(--type-heading-s-size); line-height: var(--type-heading-s-lh); } - .feed.recent p { + .feed.recent p, + .feed.blog p { font-size: var(--type-body-xs-size); line-height: var(--type-body-xs-lh); margin-bottom: 1em; } + + .blog-container { + display: flex; + gap: 20px; + } + + .left-container { + flex: 0 0 70%; /* 70% width */ + } + + .right-container { + flex: 0 0 30%; /* 30% width */ + display: flex; + flex-direction: column; + gap: 20px; + padding-top: 0; + } } @media screen and (width >= 900px) { @@ -93,13 +184,15 @@ padding: var(--spacing-xs) 0; } - .feed.recent h3 { + .feed.recent h3, + .feed.blog h3 { margin-bottom: var(--spacing-s); font-size: var(--type-heading-m-size); line-height: var(--type-heading-m-lh); } - .feed.recent .image-wrapper-el { + .feed.recent .image-wrapper-el, + .feed.blog .image-wrapper { padding-top: var(--spacing-l); margin-bottom: 0; } @@ -108,7 +201,7 @@ grid-gap: 32px; } - .feed.recent > div > div > div{ + .feed.recent > div > div > div { padding: var(--spacing-xl) var(--spacing-m); margin-bottom: var(--spacing-s); } @@ -122,7 +215,8 @@ } @media screen and (width >= 1200px) { - .feed.recent h3 { + .feed.recent h3, + .feed.blog h3 { font-size: var(--type-heading-l-size); line-height: var(--type-heading-l-lh); } @@ -131,9 +225,10 @@ padding: var(--spacing-xxl) var(--spacing-xl); } - .feed.recent p { + .feed.recent p, + .feed.blog p { font-size: var(--type-body-s-size); line-height: var(--type-body-s-lh); margin-bottom: 1em; } -} \ No newline at end of file +} diff --git a/blocks/feed/feed.js b/blocks/feed/feed.js index 10d02847e..b0e754a3e 100644 --- a/blocks/feed/feed.js +++ b/blocks/feed/feed.js @@ -1,8 +1,10 @@ import { createTag, loadFeedData, + loadBlogData, } from '../../scripts/scripts.js'; +// logic for rendering the community feed export async function renderFeed(block) { if (!block) { return; @@ -48,13 +50,107 @@ export async function renderFeed(block) { block.appendChild(parentDiv); } +// logic to render blog list home page +export async function fetchBlogContent(url) { + try { + const response = await fetch(url); + const text = await response.text(); + const parser = new DOMParser(); + const doc = parser.parseFromString(text, 'text/html'); + const content = doc.querySelector('body > main > div'); + return content ? content.innerHTML : ''; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error fetching blog content:', error); + return ''; + } +} + +export async function renderBlog(block) { + if (!block) { + return; + } + const blogIndex = window.blogindex.data; + blogIndex.reverse(); + const parentDiv = createTag('div', { class: 'blog-container' }); + + const leftContainer = createTag('div', { class: 'left-container' }); + const rightContainer = createTag('div', { class: 'right-container' }); + + const latestBlog = blogIndex[0]; + const latestBlogItem = createTag('div', { class: 'blog-item latest' }); + + // Fetch the full content of the latest blog post + const latestBlogContent = await fetchBlogContent(latestBlog.path); + if (latestBlogContent) { + // eslint-disable-next-line max-len + const truncatedContent = latestBlogContent.substring(0, Math.floor(latestBlogContent.length * 0.75)); + latestBlogItem.innerHTML = truncatedContent; + } + + const readMoreButton = createTag('button', { class: 'read-more' }, 'Read More'); + readMoreButton.addEventListener('click', () => { + window.location.href = latestBlog.path; + }); + latestBlogItem.appendChild(readMoreButton); + + leftContainer.appendChild(latestBlogItem); + + blogIndex.slice(1).forEach((page) => { + const blogItem = createTag('div', { class: 'blog-item' }); + + const h3 = createTag('h3', { class: 'title' }, page.title); + blogItem.appendChild(h3); + + const desc = createTag('p', { class: 'desc' }, page.description); + blogItem.appendChild(desc); + + const date = createTag('p', { class: 'date' }, page.publicationDate); + blogItem.appendChild(date); + + const image = createTag('p', { class: 'image-wrapper' }); + const img = createTag('img', { src: page.image }); + image.appendChild(img); + blogItem.appendChild(image); + + const blogLink = createTag('a', { href: page.path, target: '_blank', class: 'blog-link' }); + blogLink.appendChild(blogItem); + + rightContainer.appendChild(blogLink); + }); + + parentDiv.appendChild(leftContainer); + parentDiv.appendChild(rightContainer); + block.appendChild(parentDiv); +} + export default async function decorate(block) { - loadFeedData(); - if (window?.siteindex?.loaded) { - await renderFeed(block); + const isBlog = block.classList.contains('blog'); + + if (isBlog) { + loadBlogData(); + } else { + loadFeedData(); + } + + const checkDataLoaded = () => { + if (isBlog) { + return window?.blogindex?.loaded; + } + return window?.siteindex?.loaded; + }; + + const renderFunction = isBlog ? renderBlog : renderFeed; + + if (checkDataLoaded()) { + await renderFunction(block); } else { const div = createTag('div', { class: 'feed-hidden' }, ''); block.append(div); - document.addEventListener('dataset-ready', () => renderFeed(block)); + document.addEventListener('dataset-ready', () => { + if (checkDataLoaded()) { + renderFunction(block); + } + }); } } diff --git a/scripts/scripts.js b/scripts/scripts.js index 07500f4c1..5b69cc810 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -604,6 +604,24 @@ export function loadFeedData() { }); } +export function loadBlogData() { + window.blogindex = window.blogindex || { data: [], loaded: false }; + const offset = 0; + + fetch(`/query-index.json?offset=${offset}`) + .then((response) => response.json()) + .then((responseJson) => { + window.blogindex.data = responseJson?.data?.filter((entry) => entry.path.startsWith('/blog/')) || []; + window.blogindex.loaded = true; + const event = new Event('dataset-ready'); + document.dispatchEvent(event); + }) + .catch((error) => { + // eslint-disable-next-line no-console + console.log(`Error loading query index: ${error.message}`); + }); +} + /** * Decorates the main element. * @param {Element} main The main element From 5e0e854282c16d49d90eb05307df1bfa0a5e9524 Mon Sep 17 00:00:00 2001 From: asthabh23 Date: Tue, 7 Jan 2025 18:31:45 +0530 Subject: [PATCH 2/4] chore: blog page css and fixing lint issues --- styles/styles.css | 131 +++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/styles/styles.css b/styles/styles.css index 98736141f..792bd5547 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -15,7 +15,10 @@ :root { /* Fonts */ --body-font-family: "Adobe Clean", adobe-clean, "Trebuchet MS", sans-serif; - --code-font-family: "Source Code Pro", source-code-pro, "Courier New", + --code-font-family: + "Source Code Pro", + source-code-pro, + "Courier New", monospace; /* Headings (Consonant) */ @@ -152,7 +155,8 @@ /* Checkerboard pattern */ --color-checkerboard-bg-border: rgb(214 213 213 / 40%); --color-checkerboard-bg-fill: transparent; - --checkerboard-background: linear-gradient( + --checkerboard-background: + linear-gradient( var(--color-checkerboard-bg-border) 1px, transparent 1px ), @@ -177,9 +181,10 @@ --circular-number-tag-size: 60px; /* drop-shadow */ - --image-filter-drop-shadow-small: drop-shadow( - 10px 25px 50px rgba(0 0 0 / 10%) - ); + --image-filter-drop-shadow-small: + drop-shadow( + 10px 25px 50px rgba(0 0 0 / 10%) + ); /* guide-templates */ --side-navigation-bar-gap: var(--spacing-s); @@ -233,11 +238,12 @@ --card-border-radius-l: 24px; /* guide-templates */ - --side-navigation-bar-gap: clamp( - var(--spacing-m), - 3.2vw, - var(--spacing-ml) - ); + --side-navigation-bar-gap: + clamp( + var(--spacing-m), + 3.2vw, + var(--spacing-ml) + ); } } @@ -274,7 +280,8 @@ body.appear { .section.content > div, .default-content-wrapper, .contained-wrapper, -.feed.recent { +.feed.recent, +.feed.blog { max-width: var(--grid-mobile-container-width); margin-left: auto; margin-right: auto; @@ -290,7 +297,8 @@ aside { .section.content > div, .default-content-wrapper, .contained-wrapper, - .feed.recent { + .feed.recent, + .feed.blog { max-width: var(--grid-tablet-container-width); } } @@ -300,7 +308,8 @@ aside { .default-content-wrapper, .franklin .gnav .submenu-content, .contained-wrapper, - .feed.recent { + .feed.recent, + .feed.blog { max-width: 90%; } @@ -329,7 +338,8 @@ aside { .side-navigation-wrapper.expand, .side-navigation-wrapper.expand + .section.content, .franklin .gnav .submenu-content, - .feed.recent { + .feed.recent, + .feed.blog { max-width: var(--grid-desktop-container-width); } @@ -552,7 +562,8 @@ a.button.primary-cta:focus { background-color: var(--color-info-accent-hover); border-color: var(--color-info-accent-hover); color: var(--color-white); - box-shadow: 0 0 0 2px var(--color-white), + box-shadow: + 0 0 0 2px var(--color-white), 0 0 0 4px var(--color-info-accent-hover); } @@ -732,11 +743,12 @@ main .form .button::before { z-index: -1; /* 1st value: hovered color, 2nd value: original color */ - background: radial-gradient( - circle at left, - var(--color-white) 50%, - var(--spectrum-blue) 50% - ); + background: + radial-gradient( + circle at left, + var(--color-white) 50%, + var(--spectrum-blue) 50% + ); } .redesign a.button:any-link:hover::before, @@ -756,11 +768,12 @@ main .form .button:hover::before { .redesign a.button.secondary:any-link::before { /* 1st value: hovered color, 2nd value: original color */ - background: radial-gradient( - circle at left, - var(--color-font-grey) 50%, - transparent 50% - ); + background: + radial-gradient( + circle at left, + var(--color-font-grey) 50%, + transparent 50% + ); } /* .black-border button: black border transparent bg -> border button */ @@ -775,11 +788,12 @@ main .form .button:hover::before { .redesign a.button.black-border:any-link::before { /* 1st value: hovered color, 2nd value: original color */ - background: radial-gradient( - circle at left, - rgb(0 0 0 / 50%) 50%, - transparent 50% - ); + background: + radial-gradient( + circle at left, + rgb(0 0 0 / 50%) 50%, + transparent 50% + ); } /* larger size */ @@ -1154,9 +1168,13 @@ body.no-header-template { font-size: var(--type-heading-l-size); font-weight: 900; line-height: 1; - box-shadow: rgb(0 0 0 / 7%) 0 100px 148px, rgb(0 0 0 / 5%) 0 42px 62px, - rgb(0 0 0 / 4%) 0 22px 33px, rgb(0 0 0 / 3.5%) 0 13px 19px, - rgb(0 0 0 / 3%) 0 7px 10px, rgb(0 0 0 / 2%) 0 3px 4px; + /* stylelint-disable-next-line declaration-colon-newline-after */ + box-shadow: rgb(0 0 0 / 7%) 0 100px 148px, + rgb(0 0 0 / 5%) 0 42px 62px, + rgb(0 0 0 / 4%) 0 22px 33px, + rgb(0 0 0 / 3.5%) 0 13px 19px, + rgb(0 0 0 / 3%) 0 7px 10px, + rgb(0 0 0 / 2%) 0 3px 4px; margin-bottom: var(--spacing-xs); } @@ -1228,7 +1246,9 @@ body.no-header-template { right: 0; bottom: -1px; width: 0; - transition: left 0.5s var(--cubic-bezier-2), right 0.5s var(--cubic-bezier-2), + /* stylelint-disable-next-line declaration-colon-newline-after */ + transition: left 0.5s var(--cubic-bezier-2), + right 0.5s var(--cubic-bezier-2), width 0.5s var(--cubic-bezier-2); } @@ -1238,7 +1258,8 @@ body.no-header-template { left: 0; } -/* NOTE: with .breadcrumb prefix would address line length for '/' in breadcrumb, use .link-underline-effect for normal case */ +/* NOTE: with .breadcrumb prefix would address line length for '/' in breadcrumb, +use .link-underline-effect for normal case */ .breadcrumb-link-underline-effect::before { background: var(--color-light-grey-600); width: 0; @@ -1257,6 +1278,7 @@ body.no-header-template { .link-highlight-colorful-effect-2 { /* stylelint-disable-next-line property-no-vendor-prefix */ -webkit-box-decoration-break: clone; + /* stylelint-disable-next-line declaration-colon-newline-after */ background-image: linear-gradient( 90deg, rgba(137 140 242 / 50%) 0%, @@ -1273,6 +1295,7 @@ body.no-header-template { /* effect 2: greenish yellow with pink */ .link-highlight-colorful-effect-2 { + /* stylelint-disable-next-line declaration-colon-newline-after */ background-image: linear-gradient( 90deg, rgba(234 190 248 / 80%) 0%, @@ -1284,10 +1307,11 @@ body.no-header-template { /* can add `.link-highlight-colorful-effect-hover-wrapper` to trigger hover child highlight effect */ .link-highlight-colorful-effect:hover, .link-highlight-colorful-effect-2:hover, +/* stylelint-disable-next-line selector-descendant-combinator-no-non-space */ .link-highlight-colorful-effect-hover-wrapper:hover - .link-highlight-colorful-effect, +.link-highlight-colorful-effect, .link-highlight-colorful-effect-hover-wrapper:hover - .link-highlight-colorful-effect-2 { +.link-highlight-colorful-effect-2 { background-size: 100% 50%; color: inherit; } @@ -1725,10 +1749,9 @@ body.skills-template .columns ol { margin-top: 0.5em; } -body.guides-template - main - .default-content-wrapper - > :first-of-type:not(.guides-back-btn) { +body.guides-template, +main, +.default-content-wrapper > :first-of-type:not(.guides-back-btn) { margin-top: 0; } @@ -1751,6 +1774,7 @@ body.skills-template main.without-full-width-hero .default-content-wrapper h3 { letter-spacing: 0; } +/* stylelint-disable-next-line max-line-length */ body.guides-template main.without-full-width-hero .default-content-wrapper:first-of-type img:first-of-type.doc-detail-hero-image { width: 100%; height: auto; @@ -1870,7 +1894,7 @@ body.guides-template .guides-back-btn span.icon { } body.blog-template img { - max-width: 90%; + max-width: 90%; } } @@ -1905,14 +1929,11 @@ body.guides-template .guides-back-btn span.icon { margin-bottom: var(--spacing-l); } - body.guides-template - main.without-full-width-hero - .default-content-wrapper - h1, - body.skills-template - main.without-full-width-hero - .default-content-wrapper - h1 { + body.guides-template, + main.without-full-width-hero, + .default-content-wrapper, + body.skills-template, + h1 { margin-top: var(--spacing-ml); margin-bottom: var(--spacing-m); } @@ -1955,7 +1976,8 @@ body.guides-template .icon-icon-caret-down { body.guides-template .guides-back-btn .icon-icon-arrow { background-image: url("/icons/icon-arrow.svg"); - filter: invert(38%) sepia(42%) saturate(5895%) hue-rotate(203deg) + filter: + invert(38%) sepia(42%) saturate(5895%) hue-rotate(203deg) brightness(94%) contrast(92%); } @@ -2062,7 +2084,6 @@ body.contact-template main .default-content-wrapper img { } } - /* breadcrumb */ /* stylelint-disable no-descending-specificity */ @@ -2104,8 +2125,8 @@ body.contact-template main .default-content-wrapper img { font-size: var(--type-body-xxs-size); } -.breadcrumb ul li:not(:last-child) a::after { - content: '/'; +.breadcrumb ul li:not(:last-child) a::after { + content: "/"; padding-left: var(--spacing-xxs); } @@ -2162,4 +2183,4 @@ body.contact-template main .default-content-wrapper img { max-width: var(--header-container-width); padding: 0 var(--header-container-desktop-x-padding); } -} \ No newline at end of file +} From d0996c2318e8e716fadcd19616cebec3b0154765 Mon Sep 17 00:00:00 2001 From: asthabh23 Date: Tue, 7 Jan 2025 18:47:07 +0530 Subject: [PATCH 3/4] chore: css updates for layout --- blocks/feed/feed.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/blocks/feed/feed.css b/blocks/feed/feed.css index dcb141c7d..75385bb14 100644 --- a/blocks/feed/feed.css +++ b/blocks/feed/feed.css @@ -63,6 +63,7 @@ .feed.blog > div { margin-bottom: var(--spacing-s); padding: var(--spacing-ml) 0; + padding-top: 40px; gap: var(--spacing-s); } @@ -184,6 +185,10 @@ padding: var(--spacing-xs) 0; } + .feed.blog > div { + padding-top: unset; + } + .feed.recent h3, .feed.blog h3 { margin-bottom: var(--spacing-s); @@ -212,6 +217,10 @@ font-size: var(--type-body-m-size); line-height: var(--type-body-s-lh); } + + .feed.blog h1 { + margin-top: 0; + } } @media screen and (width >= 1200px) { From a88d81b88b43f51bbfe821c9b78c8d4a3d21d7f3 Mon Sep 17 00:00:00 2001 From: asthabh23 Date: Tue, 7 Jan 2025 19:29:34 +0530 Subject: [PATCH 4/4] chore: update CTA button style --- blocks/feed/feed.css | 26 +++++++++++++------------- blocks/feed/feed.js | 2 +- styles/styles.css | 6 ++++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/blocks/feed/feed.css b/blocks/feed/feed.css index 75385bb14..cd31eab8c 100644 --- a/blocks/feed/feed.css +++ b/blocks/feed/feed.css @@ -29,21 +29,21 @@ box-shadow: 0 8px 16px rgba(0 0 0 / 40%); } -.read-more { - display: inline-block; - margin-top: 10px; - padding: 10px 20px; - border-radius: 25px; - width: 150px; - background-color: var(--spectrum-blue); - color: white; - border: none; - cursor: pointer; - text-align: center; +.left-container { + display: flex; + flex-direction: column; + align-items: center; } -.read-more:hover { - background-color: var(--dark-spectrum-blue); +.left-container .blog-item.latest:not(.read-more) { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.left-container .read-more { + align-self: center; + display: inline-block; } .feed.recent .feed-item { diff --git a/blocks/feed/feed.js b/blocks/feed/feed.js index b0e754a3e..aa4647d1a 100644 --- a/blocks/feed/feed.js +++ b/blocks/feed/feed.js @@ -88,7 +88,7 @@ export async function renderBlog(block) { latestBlogItem.innerHTML = truncatedContent; } - const readMoreButton = createTag('button', { class: 'read-more' }, 'Read More'); + const readMoreButton = createTag('a', { href: latestBlog.path, class: 'read-more button primary large' }, 'Read More'); readMoreButton.addEventListener('click', () => { window.location.href = latestBlog.path; }); diff --git a/styles/styles.css b/styles/styles.css index 792bd5547..46e22b92a 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -685,7 +685,8 @@ a.button > svg > use { /* primary button: blue bg */ .redesign a.button:any-link, -main .form .button { +main .form .button, +.feed.blog .read-more { cursor: pointer; text-decoration: none; padding: 5.5px 15px; @@ -721,7 +722,8 @@ main .form .button { } .redesign a.button:any-link:hover, -main .form .button:hover { +main .form .button:hover, +.feed.blog .read-more:hover { color: var(--spectrum-blue); border-color: var(--spectrum-blue); transform: translateZ(0);