Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Party #273

Merged
merged 12 commits into from
Jun 19, 2023
8 changes: 8 additions & 0 deletions blocks/card-list/card-list.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.card-list-wrapper .cards .cards-card-details dialog[aria-expanded="true"] {
display: contents;
color: inherit;
}

.card-list-wrapper .cards .cards-card-details {
overflow-x: hidden;
}
66 changes: 66 additions & 0 deletions blocks/card-list/card-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { buildBlock, decorateBlock, loadBlock } from '../../scripts/scripts.js';

function toggleVisibility(dialog) {
const expanded = dialog.getAttribute('aria-expanded') === 'true';
dialog.setAttribute('aria-expanded', expanded ? 'false' : 'true');
}

function urlify(str) {
return str.replace(/(https:\/\/[^ "]+)/g, (url) => `<a href="${url}" target="_blank">Link</a>`);
}

function stripTags(html, ...args) {
return html.replace(/<(\/?)(\w+)[^>]*\/?>/g, (_, endMark, tag) => {
if (args.includes(tag)) return `<${endMark}${tag}>`;
return '';
}).replace(/<!--.*?-->/g, '');
}

export default async function decorate(block) {
const endpoint = block.querySelector('a').href;
block.textContent = '';
const blockParty = await fetch(endpoint);
const blockPartyJson = await blockParty.json();
if (blockPartyJson.data && (blockPartyJson.data.length > 0)) {
// create a 2D array to pass to the cards block
const cardsArr = [];
let cardsRow = [];
const blockPartyList = blockPartyJson.data.filter((row) => row.approved === 'true');
await blockPartyList.forEach(async (row, i) => {
// limit each row to only 4 columns, otherwise create a new row
if ((i !== 0) && (i % 4) === 0) {
cardsArr.push(cardsRow);
cardsRow = [];
}
let cardDetails = `<p><a href="${stripTags(row.githubUrl)}" target="_blank">${stripTags(row.title)}</a></p>`;
if (row.showcaseUrl) {
cardDetails += `<p><a href="${stripTags(row.showcaseUrl)}" target="_blank">Preview</a></p>`;
}
cardDetails += `<p><em>${stripTags(row.category)}</em></p>
<p><em>${stripTags(row.firstName)} ${stripTags(row.lastName)}, ${stripTags(row.company)}</em></p>
<p class="description">${urlify(stripTags(row.description), 'b', 'i', 'u', 'p', 'br')}</p>`;
cardsRow.push(cardDetails);
});
cardsArr.push(cardsRow);

// build out cards using the existing cards block
const cardsBlock = buildBlock('cards', cardsArr);
// replace existing block with the new cards block
const blockWrapper = block.parentElement;
block.remove();
blockWrapper.append(cardsBlock);
// decorate and load the cards block
decorateBlock(cardsBlock);
await loadBlock(cardsBlock);

// add listener to hide/show the description overflow dialog
const dialogs = blockWrapper.querySelectorAll('.cards-card dialog');
dialogs.forEach((dialog) => {
const description = dialog.parentElement.querySelector('p.description');
description.addEventListener('click', (event) => {
toggleVisibility(dialog);
event.stopPropagation();
});
});
}
}