Skip to content

Commit

Permalink
TV scroller buttons / shadows (#120)
Browse files Browse the repository at this point in the history
* Button nav

* Determine scroll limits for buttons

* Shadows

* Revised buttons

* Responsive

* Pluralize show count

* Update components/Tv/TVCategory.vue

Co-authored-by: Pascal Jufer <[email protected]>

* Update components/Tv/TVCategory.vue

Co-authored-by: Pascal Jufer <[email protected]>

* Updated badge

---------

Co-authored-by: Pascal Jufer <[email protected]>
  • Loading branch information
phazonoverload and paescuj authored Jan 25, 2024
1 parent bdc331e commit 536398f
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 26 deletions.
1 change: 1 addition & 0 deletions assets/css/tv.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
:root {
--tv-background: #0c1628;
--gray: #9da6b3;
}

body.tv {
Expand Down
158 changes: 140 additions & 18 deletions components/Tv/TVCategory.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
<template>
<div class="category">
<h2>{{ title }}</h2>
<ul>
<li v-for="show in shows" :key="show.shows_id.id">
<TVShow
:slug="show.shows_id.slug"
:tile="show.shows_id.tile"
:title="show.shows_id.title"
:description="show.shows_id.one_liner"
/>
</li>
</ul>
<div class="top">
<div class="title">
<h2>{{ title }}</h2>
<div class="badge" color="light">{{ shows.length }}</div>
</div>
<div v-if="canScroll" class="nav">
<button :class="{ active: !leftLimit }" @click="scroll('left')">
<BaseIcon name="arrow_circle_left" size="medium" />
</button>
<button :class="{ active: !rightLimit }" @click="scroll('right')">
<BaseIcon name="arrow_circle_right" size="medium" />
</button>
</div>
</div>
<div :class="{ 'left-shadow': !leftLimit, 'right-shadow': !rightLimit }" class="scroller-container">
<ul ref="scroller" @scroll="determineScrollLimits">
<li v-for="show in shows" :key="show.shows_id.id">
<TVShow
:slug="show.shows_id.slug"
:tile="show.shows_id.tile"
:title="show.shows_id.title"
:description="show.shows_id.one_liner"
/>
</li>
</ul>
</div>
</div>
</template>

Expand All @@ -19,23 +34,130 @@ defineProps({
title: String,
shows: Array,
});
const scroller = ref(null);
const canScroll = ref(false);
const rightLimit = ref(false);
const leftLimit = ref(true);
function determineScrollLimits() {
const s = scroller.value;
canScroll.value = s.clientWidth < s.scrollWidth;
leftLimit.value = s.scrollLeft == 0;
rightLimit.value = s.scrollWidth - Math.round(s.scrollLeft) == s.offsetWidth;
}
function scroll(val) {
const showWidth = parseInt(getComputedStyle(scroller.value.children[0]).getPropertyValue('width'));
if (val == 'right') {
scroller.value.scrollLeft += showWidth;
}
if (val == 'left') {
scroller.value.scrollLeft -= showWidth;
}
}
onMounted(() => {
determineScrollLimits();
window.addEventListener('resize', determineScrollLimits);
});
onUnmounted(() => {
window.removeEventListener('resize', determineScrollLimits);
});
</script>

<style lang="scss" scoped>
.category {
h2 {
color: #64748b;
font-size: 1rem;
margin: 0 0 0.5rem;
.top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
.title {
--title-color: #64748b;
display: flex;
align-items: center;
gap: 0.5rem;
h2 {
color: var(--title-color);
font-size: 1rem;
margin: 0;
}
.badge {
background: var(--title-color);
font-size: 0.75rem;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2rem;
}
}
.nav {
display: flex;
gap: 0.5rem;
}
button {
opacity: 0.25;
&.active {
opacity: 1;
cursor: pointer;
}
}
}
.scroller-container {
width: 100%;
position: relative;
&.left-shadow:before,
&.right-shadow:after {
content: '';
display: block;
z-index: 1;
position: absolute;
top: 0;
bottom: 0;
pointer-events: none;
width: 50px;
height: 100%;
opacity: 0.5;
}
&.left-shadow:before {
left: 0;
background: linear-gradient(90deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
}
&.right-shadow:after {
right: 0;
background: linear-gradient(90deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1));
}
}
ul {
--show-gap: 10px;
--show-size: 300px;
margin-top: 0;
padding-left: 0;
list-style-type: none;
display: flex;
gap: 2em;
overflow-x: scroll;
gap: var(--show-gap);
overflow-x: auto;
padding-bottom: 1em;
display: flex;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
li {
width: var(--show-size);
flex-shrink: 0;
scroll-snap-align: start;
}
@media (width > 60rem) {
ul {
--show-gap: 20px;
--show-size: 325px;
}
}
}
</style>
10 changes: 2 additions & 8 deletions components/Tv/TVShow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defineProps({

<style lang="scss" scoped>
.show {
width: 200px;
width: 100%;
display: block;
text-decoration: none;
img {
Expand All @@ -36,17 +36,11 @@ defineProps({
margin-top: 0.75rem;
}
p {
color: #9da6b3;
color: var(--gray-600);
opacity: 0.8;
font-size: 0.8rem;
margin-top: 0.5rem;
line-height: var(--line-height-sm);
}
}
@media (width > 60rem) {
.show {
width: 300px;
}
}
</style>

0 comments on commit 536398f

Please sign in to comment.