merch sizing-guide: add filter
All checks were successful
/ build (push) Successful in 11s

This commit is contained in:
kritzl 2025-02-14 02:08:10 +01:00
commit 358bc7d211
Signed by: kritzl
SSH key fingerprint: SHA256:5BmINP9VjZWaUk5Z+2CTut1KFhwLtd0ZynMekKbtViM
5 changed files with 364 additions and 163 deletions

1184
styleguide/merch/index.html Normal file

File diff suppressed because one or more lines are too long

197
styleguide/merch/merch.js Normal file
View file

@ -0,0 +1,197 @@
const sizes = [
"XXS", "XS", "S", "M", "L", "XL", "2XL", "3XL", "4XL", "5XL", "6XL"
]
function selectCell(e) {
const cell = e.target;
const value = parseFloat(cell.dataset.val);
const col = cell.dataset.col;
const dimension = cell.dataset.dim;
document.querySelectorAll('td.val:not(.empty)').forEach(match => {
match.dataset.diff = '';
match.classList.remove('highlighted')
match.classList.remove('currentDimension')
if (match.dataset.dim === dimension) {
match.classList.add('currentDimension')
const diff = parseFloat(match.dataset.val) - value;
match.dataset.diff = diff > 0 ? `+${diff}` : diff;
if (match.dataset.dim === 'A') match.style.cssText = `--custom-color: rgba(96, 165, 249, ${1 - Math.abs(diff) / 5})`
if (match.dataset.dim === 'B') match.style.cssText = `--custom-color: rgba(211, 129, 247, ${1 - Math.abs(diff) / 5})`
if (match.dataset.dim === 'C') match.style.cssText = `--custom-color: rgba(255, 121, 117, ${1 - Math.abs(diff) / 5})`
}
});
document.querySelectorAll('td.dimension').forEach(match => {
match.classList.remove('currentDimension');
if (match.innerHTML === dimension) {
match.classList.add('currentDimension');
}
});
cell.classList.add('highlighted')
}
function selectCellPlus(e) {
e.stopPropagation();
const cell = e.target;
const group = cell.parentElement.parentElement;
const col = cell.dataset.col;
if (cell.classList.contains('highlighted') && !cell.classList.contains('currentDimension')) {
selectCell(e);
return;
}
const values = {}
group.querySelectorAll(`td[data-col='${col}']`).forEach(match => {
values[match.dataset.dim] = parseFloat(match.dataset.val);
})
document.querySelectorAll('td.val:not(.empty)').forEach(match => {
match.dataset.diff = '';
match.classList.remove('highlighted')
match.classList.remove('currentDimension')
if (match.dataset.dim in values) {
const diff = parseFloat(match.dataset.val) - values[match.dataset.dim];
match.dataset.diff = diff > 0 ? `+${diff}` : diff;
if (match.dataset.dim === 'A') match.style.cssText = `--custom-color: rgba(96, 165, 249, ${1 - Math.abs(diff) / 5})`
if (match.dataset.dim === 'B') match.style.cssText = `--custom-color: rgba(211, 129, 247, ${1 - Math.abs(diff) / 5})`
if (match.dataset.dim === 'C') match.style.cssText = `--custom-color: rgba(255, 121, 117, ${1 - Math.abs(diff) / 5})`
}
});
document.querySelectorAll('td.dimension').forEach(match => {
match.classList.remove('currentDimension');
});
group.querySelectorAll(`td[data-col='${col}']`).forEach(match => {
match.classList.add('highlighted')
})
}
function hoverCell(e) {
const cell = e.target;
const group = cell.parentElement.parentElement;
const col = cell.dataset.col;
const dim = cell.dataset.dim;
hoverOff()
document.querySelectorAll('table > thead > tr > th').forEach(match => {
if (match.dataset.col === col) match.classList.add('hover')
});
group.querySelectorAll('td.dimension').forEach(match => {
if (match.innerText === dim) match.classList.add('hover')
});
group.querySelectorAll('td:not(.dimension), th').forEach(match => {
match.classList.add('hover')
});
}
function hoverOff() {
document.querySelectorAll('table > thead > tr > th').forEach(match => {
match.classList.remove('hover')
});
document.querySelectorAll('td.dimension, td, th').forEach(match => {
match.classList.remove('hover')
});
}
const typeList = new Set()
const fitList = new Set()
document.querySelectorAll('tbody').forEach(tbody => {
if (tbody.dataset.from) {
const source = document.querySelector(`tbody#${tbody.dataset.from}`)
if (!source) {
console.log(`tbody with ID '${tbody.dataset.from}' not found.`);
return;
}
const name = tbody.querySelector('tr th').innerHTML;
tbody.replaceChildren()
tbody.insertAdjacentHTML("afterbegin", source.innerHTML)
tbody.querySelector('tr th').innerHTML = name;
delete tbody.dataset.from;
tbody.dataset.type = source.dataset.type;
tbody.dataset.fit = source.dataset.fit;
}
typeList.add(tbody.dataset.type);
fitList.add(tbody.dataset.fit);
});
// build filter
const filterTypeElement = document.querySelector('#filterType');
typeList.forEach(type => {
filterTypeElement.insertAdjacentHTML('beforeend', `<label>
<input type="checkbox" value="${type}" checked>
${type}
</label>`)
})
const filterFitElement = document.querySelector('#filterFit');
fitList.forEach(fit => {
filterFitElement.insertAdjacentHTML('beforeend', `<label>
<input type="checkbox" value="${fit}" checked>
${fit}
</label>`)
})
const filterType = new Set(typeList);
const filterFit = new Set(fitList);
function filter() {
document.querySelectorAll(`tbody`).forEach(match => {
match.classList.toggle('filtered', !filterType.has(match.dataset.type) || !filterFit.has(match.dataset.fit));
})
}
filterTypeElement.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
checkbox.addEventListener('change', (e) => {
if (checkbox.checked) {
filterType.add(checkbox.value)
} else {
filterType.delete(checkbox.value)
}
filter();
});
});
filterFitElement.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
checkbox.addEventListener('change', (e) => {
if (checkbox.checked) {
filterFit.add(checkbox.value)
} else {
filterFit.delete(checkbox.value)
}
filter();
});
});
document.querySelectorAll('td.val').forEach(cell => {
const rowTitle = cell.parentElement.querySelector('th');
cell.dataset.col = sizes[rowTitle !== null ? cell.cellIndex - 4 : cell.cellIndex - 1];
cell.addEventListener('pointerenter', hoverCell);
cell.addEventListener('pointerleave', hoverOff);
});
// initialize table
document.querySelectorAll('td.val:not(.empty)').forEach(cell => {
cell.dataset.val = cell.innerText;
cell.dataset.diff = '';
cell.dataset.dim = cell.parentElement.querySelector('td.dimension').innerHTML;
cell.addEventListener('click', selectCellPlus);
});
// disable select on click outside value cell
document.addEventListener('click', e => {
document.querySelectorAll('td.val:not(.empty)').forEach(match => {
match.dataset.diff = '';
match.classList.remove('highlighted')
match.classList.remove('currentDimension')
});
document.querySelectorAll('td.dimension').forEach(match => {
match.classList.remove('currentDimension');
});
});