Merge pull request #868 from roboflow/cookbooks/cards-improvements
[Cookbooks] - Improved functionality of cookbook cards
This commit is contained in:
commit
5b2bdf58e7
|
|
@ -1,26 +1,51 @@
|
|||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
async function setCard(el, url, name, desc, labels, version, theme, authors) {
|
||||
const palette = __md_get("__palette")
|
||||
const useDark = palette && typeof palette.color === "object" && palette.color.scheme === "slate"
|
||||
const theme = useDark ? "dark-theme" : "light-default";
|
||||
|
||||
const colorList = [
|
||||
"#22c55e",
|
||||
"#14b8a6",
|
||||
"#ef4444",
|
||||
"#eab308",
|
||||
"#8b5cf6",
|
||||
"#f97316",
|
||||
"#3b82f6",
|
||||
"#22c55e",
|
||||
"#14b8a6",
|
||||
"#ef4444",
|
||||
"#eab308",
|
||||
"#8b5cf6",
|
||||
"#f97316",
|
||||
"#3b82f6",
|
||||
]
|
||||
|
||||
let labelHTML = ''
|
||||
if (labels) {
|
||||
const labelArray = labels.split(',').map((label, index) => {
|
||||
const color = colorList[index % colorList.length]
|
||||
return `<span class="non-selectable-text" style="background-color: ${color}; color: #fff; padding: 2px 4px; border-radius: 4px; margin-right: 4px;">${label}</span>`
|
||||
})
|
||||
const repoCards = document.querySelectorAll(".repo-card");
|
||||
const labelsAll = Array
|
||||
.from(repoCards)
|
||||
.flatMap((element) => element.getAttribute('data-labels').split(','))
|
||||
.map(label => label.trim())
|
||||
.filter(label => label !== '');
|
||||
const uniqueLabels = [...new Set(labelsAll)];
|
||||
|
||||
labelHTML = labelArray.join(' ')
|
||||
}
|
||||
const labelToColor = uniqueLabels.reduce((map, label, index) => {
|
||||
map[label] = colorList[index % colorList.length];
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
|
||||
async function renderCard(element, elementIndex) {
|
||||
const url = element.getAttribute('data-url');
|
||||
const name = element.getAttribute('data-name');
|
||||
const labels = element.getAttribute('data-labels');
|
||||
const version = element.getAttribute('data-version');
|
||||
const authors = element.getAttribute('data-author');
|
||||
|
||||
const labelHTML = labels ? labels.split(',').filter(label => label !== '').map((label, index) => {
|
||||
const color = labelToColor[label.trim()];
|
||||
return `
|
||||
<span
|
||||
class="label non-selectable-text"
|
||||
style="background-color: ${color}"
|
||||
>
|
||||
${label.trim()}
|
||||
</span>
|
||||
`;
|
||||
}).join(' ') : '';
|
||||
|
||||
const authorArray = authors.split(',');
|
||||
const authorDataArray = await Promise.all(authorArray.map(async (author) => {
|
||||
|
|
@ -28,36 +53,51 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
return await response.json();
|
||||
}));
|
||||
|
||||
let authorHTML = '';
|
||||
authorDataArray.forEach((authorData, index) => {
|
||||
const marginLeft = index === 0 ? '0' : '-15px';
|
||||
authorHTML += `
|
||||
<div class="author-container" style="display: inline-block; margin-left: ${marginLeft}; position: relative;">
|
||||
<a href="https://github.com/${authorData.login}" target="_blank">
|
||||
<img src="${authorData.avatar_url}" width="32" height="32" style="border-radius: 50%;" />
|
||||
</a>
|
||||
<div class="tooltip" style="visibility: hidden; background-color: #555; color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -60px; opacity: 0; transition: opacity 0.3s; width: 120px;">
|
||||
${authorData.login}
|
||||
</div>
|
||||
</div>
|
||||
let authorAvatarsHTML = authorDataArray.map((authorData, index) => {
|
||||
const marginLeft = index === 0 ? '0' : '-10px';
|
||||
const zIndex = 100 - index;
|
||||
return `
|
||||
<div
|
||||
class="author-container"
|
||||
data-login="${authorData.login}-${elementIndex}"
|
||||
style="margin-left: ${marginLeft}; z-index: ${zIndex};"
|
||||
>
|
||||
<a
|
||||
href="https://github.com/${authorData.login}"
|
||||
target="_blank"
|
||||
style="line-height: 0;"
|
||||
>
|
||||
<img
|
||||
class="author-avatar"
|
||||
src="${authorData.avatar_url}"
|
||||
alt="${authorData.login}'s avatar"
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}).join('');
|
||||
|
||||
document.querySelectorAll('.author-container').forEach((container) => {
|
||||
const tooltip = container.querySelector('.tooltip');
|
||||
container.addEventListener('mouseover', () => {
|
||||
tooltip.style.visibility = 'visible';
|
||||
tooltip.style.opacity = '1';
|
||||
});
|
||||
container.addEventListener('mouseout', () => {
|
||||
tooltip.style.visibility = 'hidden';
|
||||
tooltip.style.opacity = '0';
|
||||
});
|
||||
});
|
||||
let authorNamesHTML = authorDataArray.map(
|
||||
authorData => `
|
||||
<span
|
||||
class="author-name"
|
||||
data-login="${authorData.login}-${elementIndex}"
|
||||
style="color: ${theme.color}"
|
||||
>
|
||||
<a href="https://github.com/${authorData.login}" target="_blank">
|
||||
${authorData.login}
|
||||
</a>
|
||||
</span>`
|
||||
).join(', ');
|
||||
|
||||
let authorsHTML = `
|
||||
<div class="authors">
|
||||
${authorAvatarsHTML}
|
||||
<div class="author-names">${authorNamesHTML}</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
el.innerText = `
|
||||
element.innerText = `
|
||||
<a style="text-decoration: none; color: inherit;" href="${url}">
|
||||
<div style="flex-direction: column; height: 100%; display: flex;
|
||||
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; background: ${theme.background}; font-size: 14px; line-height: 1.5; color: ${theme.color}">
|
||||
|
|
@ -66,19 +106,14 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
${name}
|
||||
</span>
|
||||
</div>
|
||||
<div style="font-size: 12px; margin-top: 0.5rem; color: ${theme.color}; flex: 1;">
|
||||
${desc}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; justify-content: flex-start; margin-bottom: 1rem; margin-top: 1rem">
|
||||
${authorHTML}
|
||||
</div>
|
||||
${authorsHTML}
|
||||
<div style="font-size: 12px; color: ${theme.color}; display: flex; flex: 0; justify-content: space-between">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="/assets/supervision-lenny.png" aria-label="stars" width="20" height="20" role="img" />
|
||||
|
||||
<span style="margin-left: 4px">${version}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div style="display: flex; align-items: center; flex-wrap: wrap">
|
||||
${labelHTML}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -86,23 +121,22 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
</a>
|
||||
`
|
||||
|
||||
let sanitizedHTML = DOMPurify.sanitize(el.innerText);
|
||||
el.innerHTML = sanitizedHTML;
|
||||
}
|
||||
for (const el of document.querySelectorAll('.repo-card')) {
|
||||
const url = el.getAttribute('data-url');
|
||||
const name = el.getAttribute('data-name');
|
||||
const desc = el.getAttribute('data-desc');
|
||||
const labels = el.getAttribute('data-labels');
|
||||
const version = el.getAttribute('data-version');
|
||||
const authors = el.getAttribute('data-author');
|
||||
const palette = __md_get("__palette")
|
||||
if (palette && typeof palette.color === "object") {
|
||||
var theme = palette.color.scheme === "slate" ? "dark-theme" : "light-default"
|
||||
} else {
|
||||
var theme = "light-default"
|
||||
}
|
||||
let sanitizedHTML = DOMPurify.sanitize(element.innerText);
|
||||
element.innerHTML = sanitizedHTML;
|
||||
|
||||
setCard(el, url, name, desc, labels, version, theme, authors);
|
||||
document.querySelectorAll('.author-name').forEach(element => {
|
||||
element.addEventListener('mouseenter', function() {
|
||||
const login = this.getAttribute('data-login');
|
||||
document.querySelector(`.author-container[data-login="${login}"]`).classList.add('hover');
|
||||
});
|
||||
|
||||
element.addEventListener('mouseleave', function() {
|
||||
const login = this.getAttribute('data-login');
|
||||
document.querySelector(`.author-container[data-login="${login}"]`).classList.remove('hover');
|
||||
});
|
||||
});
|
||||
}
|
||||
repoCards.forEach((element, index) => {
|
||||
renderCard(element, index);
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -31,20 +31,72 @@
|
|||
transform: translateY(-0.125rem); /* Move up by -0.125rem on hover */
|
||||
}
|
||||
|
||||
.portfolio-section {
|
||||
padding-bottom: 1rem;
|
||||
.authors {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.md-typeset h1 {
|
||||
margin: 0 0 0.75rem;
|
||||
.author-names {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.author-name {
|
||||
opacity: 0;
|
||||
.author-container {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
div:hover .author-name {
|
||||
opacity: 1;
|
||||
.author-container.hover {
|
||||
transform: translateY(-0.125rem);
|
||||
}
|
||||
|
||||
.author-container:hover {
|
||||
transform: translateY(-0.125rem);
|
||||
}
|
||||
|
||||
.author-container a {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.author-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.author-name a {
|
||||
color: inherit; /* Inherits the color from the parent element */
|
||||
text-decoration: none; /* Removes the underline */
|
||||
}
|
||||
|
||||
.author-name a:hover {
|
||||
color: inherit; /* Inherits the color from the parent element */
|
||||
text-decoration: underline; /* Adds underline on hover */
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #fff;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.non-selectable-text {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<h1>Supervision Cookbooks</h1>
|
||||
</div>
|
||||
<div class="custom-grid">
|
||||
<p class="card repo-card" data-url="/develop/notebooks/quickstart" data-name="Supervision Quickstart" data-desc="Quickstart to Supervision" data-labels="ANNOTATORS,DETECTIONS,SAM" data-version="v0.18.0" data-author="SkalskiP,onuralpszr"></p>
|
||||
<p class="card repo-card" data-url="/develop/notebooks/quickstart" data-name="Supervision Quickstart" data-labels="ANNOTATORS,DETECTIONS,SAM" data-version="v0.18.0" data-author="SkalskiP,onuralpszr"></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Reference in New Issue