feat: add filter list component

This commit is contained in:
Sebin Nyshkim 2025-05-02 16:50:24 +02:00
parent aa410f916a
commit 9d9e00c560
3 changed files with 287 additions and 48 deletions

View file

@ -0,0 +1,230 @@
<script webc:setup>
const ratings = ['No', 'Maybe', 'Yes', 'Love'];
const getRating = (rating) => ratings[rating];
const getSorted = (collection) => collection.sort((a, b) => b.rating - a.rating);
</script>
<div webc:root="override">
<div class="buttons">
<div class="filter-button" webc:for="rating of ratings">
<input type="checkbox" :name="rating" :id="`button-${rating.toLowerCase()}`" />
<label :for="`button-${rating.toLowerCase()}`" @text="rating"></label>
</div>
</div>
<ul class="list">
<li webc:for="row of getSorted(data)" class="item" :class="getRating(row.rating).toLowerCase()">
<span class="tag rating" :class="getRating(row.rating).toLowerCase()">
<span @text="getRating(row.rating)"></span>
</span>
<span class="name" @text="row.name"></span
><span class="tag receive" webc:if="row.receive"><span>Receive</span></span
><span class="tag give" webc:if="row.give"><span>Give</span></span>
</li>
</ul>
<p class="intro">Select one of the categories above</p>
</div>
<style webc:scoped="filter-list">
:host {
--clr-love: oklch(60% 0.25 10deg);
--clr-yes: oklch(65% 0.2 140deg);
--clr-maybe: oklch(75% 0.15 85deg);
--clr-no: oklch(40% 0.15 30deg);
--clr-tag: oklch(65% 0.15 245deg);
}
:host {
position: relative;
background: linear-gradient(
to bottom right,
var(--clr-box-gradient-start) 0%,
var(--clr-box-gradient-end) 50%
);
font-size: 0.75em;
box-shadow: 0.125em 0.125em 0.5em var(--clr-box-shadow);
margin-block: 1em;
border-radius: 1em;
padding-block: 0 1em;
z-index: 1;
@media (min-width: 40em) {
font-size: 1em;
}
}
:host::before {
content: '';
position: absolute;
inset: var(--border-thin);
background: linear-gradient(
to bottom right,
var(--clr-quick-info-bg-start) 0%,
var(--clr-quick-info-bg-end) 50%
);
border-radius: inherit;
z-index: -1;
}
:host .buttons {
display: flex;
flex-flow: row-reverse nowrap;
gap: 0.75em;
padding: 0.5em 0.75em;
}
:host .filter-button {
flex: 1 1 0;
}
:host .filter-button input {
display: none;
}
:host .filter-button input:checked + label {
--box-shadow-size: 0.25em;
--button-top: 0.25em;
}
:host .filter-button label {
display: block;
position: relative;
top: var(--button-top, 0);
background-color: var(--clr-button);
font-weight: 700;
text-decoration: none;
text-align: center;
color: var(--theme-c-primary-100);
margin: 0.5em 0;
border-radius: 0.25em;
padding: 0.5em 1em;
box-shadow: 0 var(--box-shadow-size, 0.5em) 0 0 oklch(from var(--clr-button) calc(l - 0.3) c h);
transition: all 0.1s ease-out;
}
:host .filter-button label:hover {
--box-shadow-size: 0.75em;
--button-top: -0.25em;
cursor: pointer;
}
:host .filter-button label[for='button-love'] {
--clr-button: var(--clr-love);
}
:host .filter-button label[for='button-yes'] {
--clr-button: var(--clr-yes);
}
:host .filter-button label[for='button-maybe'] {
--clr-button: var(--clr-maybe);
}
:host .filter-button label[for='button-no'] {
--clr-button: var(--clr-no);
}
:host .list {
list-style: none;
max-height: 30em;
margin: 0;
padding: 0;
overflow: scroll;
}
:host .item {
display: none;
}
:host .item:hover {
background-color: rgb(0 0 0 / 0.3);
}
:host:has(#button-love:checked) .item.love,
:host:has(#button-yes:checked) .item.yes,
:host:has(#button-maybe:checked) .item.maybe,
:host:has(#button-no:checked) .item.no {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
gap: 0.5em;
padding-block: 0.25em;
padding-inline: 0.875em;
}
:host .intro {
font-size: 2em;
font-weight: bold;
font-style: italic;
text-align: center;
hyphens: none;
}
:host:has(input:checked) .intro {
display: none;
}
:host .item .rating {
flex: 0 0 5em;
}
:host .item .name {
flex: 1 0 0;
}
:host .item .tag {
display: block;
font-size: 0.75em;
font-weight: bold;
text-align: center;
color: var(--theme-c-primary-100);
background: var(--tag-bg);
border: 0.125em solid oklch(from var(--tag-bg) calc(l - 0.1) c h);
border-radius: 1em;
padding: 0 0.5em;
}
:host .item .rating.love {
--tag-bg: var(--clr-love);
}
:host .item .rating.yes {
--tag-bg: var(--clr-yes);
}
:host .item .rating.maybe {
--tag-bg: var(--clr-maybe);
}
:host .item .rating.no {
--tag-bg: var(--clr-no);
}
:host .item .tag.receive {
--tag-bg: var(--clr-tag);
}
:host .item .tag.give {
--tag-bg: oklch(from var(--clr-tag) calc(l - 0.1) calc(c - 0.1) h);
}
</style>