forked from DebaucheryLibrarian/traxxx
Using query instead of parameters for tag filter URI. Added generic scrolling component, using for actor photos and entity children. Removed pagination from filter bar.
This commit is contained in:
236
assets/components/scroll/scroll.vue
Normal file
236
assets/components/scroll/scroll.vue
Normal file
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div class="scroll">
|
||||
<Expand
|
||||
v-if="expanded"
|
||||
:expanded="expanded"
|
||||
class="expand-dark"
|
||||
@expand="(state) => expanded = state"
|
||||
/>
|
||||
|
||||
<Expand
|
||||
v-if="expanded"
|
||||
:expanded="expanded"
|
||||
class="expand-light"
|
||||
@expand="(state) => expanded = state"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-show="enabled && !expanded"
|
||||
class="scroll-button scroll-left noselect"
|
||||
:class="{ 'scroll-start': scrollAtStart }"
|
||||
@click="scroll('left')"
|
||||
><Icon icon="arrow-left3" /></div>
|
||||
|
||||
<slot v-if="!expanded" />
|
||||
|
||||
<slot
|
||||
v-if="expanded"
|
||||
name="expanded"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-show="enabled && !expanded"
|
||||
class="scroll-button scroll-right noselect"
|
||||
:class="{ 'scroll-end': scrollAtEnd }"
|
||||
@click="scroll('right')"
|
||||
><Icon icon="arrow-right3" /></div>
|
||||
|
||||
<Expand
|
||||
v-if="expandable && scrollable"
|
||||
:expanded="expanded"
|
||||
class="expand-dark"
|
||||
@expand="(state) => expanded = state"
|
||||
/>
|
||||
|
||||
<Expand
|
||||
v-if="expandable && scrollable"
|
||||
:expanded="expanded"
|
||||
class="expand-light"
|
||||
@expand="(state) => expanded = state"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Expand from '../expand/expand.vue';
|
||||
|
||||
function updateScroll() {
|
||||
this.scrollable = this.target.scrollWidth > this.target.clientWidth;
|
||||
this.scrollAtStart = this.target.scrollLeft === 0;
|
||||
this.scrollAtEnd = this.target.scrollWidth - this.target.clientWidth === this.target.scrollLeft;
|
||||
}
|
||||
|
||||
function scroll(direction) {
|
||||
if (direction === 'right') {
|
||||
this.target.scrollLeft = this.target.scrollLeft + this.target.clientWidth - 100;
|
||||
}
|
||||
|
||||
if (direction === 'left') {
|
||||
this.target.scrollLeft = this.target.scrollLeft - this.target.clientWidth + 100;
|
||||
}
|
||||
}
|
||||
|
||||
function mounted() {
|
||||
this.target = this.$slots.default[0].elm;
|
||||
|
||||
this.target.addEventListener('scroll', () => {
|
||||
this.updateScroll();
|
||||
});
|
||||
|
||||
window.addEventListener('resize', this.updateScroll);
|
||||
this.updateScroll();
|
||||
}
|
||||
|
||||
function beforeDestroy() {
|
||||
this.target.removeEventListener('scroll', this.updateScroll);
|
||||
window.removeEventListener('resize', this.updateScroll);
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Expand,
|
||||
},
|
||||
props: {
|
||||
enabled: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
expandable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
target: null,
|
||||
scrollable: true,
|
||||
scrollAtStart: true,
|
||||
scrollAtEnd: false,
|
||||
expanded: false,
|
||||
};
|
||||
},
|
||||
mounted,
|
||||
beforeDestroy,
|
||||
methods: {
|
||||
scroll,
|
||||
updateScroll,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import 'theme';
|
||||
|
||||
.scroll {
|
||||
background: var(--profile);
|
||||
position: relative;
|
||||
padding: 0 1rem 0 0;
|
||||
|
||||
&.expanded {
|
||||
padding: 0;
|
||||
|
||||
.scroll {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-light {
|
||||
background: var(--background-dim);
|
||||
|
||||
.scroll-button {
|
||||
.icon {
|
||||
fill: var(--darken);
|
||||
}
|
||||
|
||||
&.scroll-start .icon,
|
||||
&.scroll-end .icon {
|
||||
fill: var(--darken-weak);
|
||||
}
|
||||
|
||||
&:hover:not(.scroll-start):not(.scroll-end) .icon {
|
||||
fill: var(--text-dark);
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-left {
|
||||
background: linear-gradient(to right, var(--background-dim) 50%, transparent);
|
||||
}
|
||||
|
||||
.scroll-right {
|
||||
background: linear-gradient(to left, var(--background-dim) 50%, transparent);
|
||||
}
|
||||
|
||||
.expand-dark {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-dark {
|
||||
background: var(--profile);
|
||||
|
||||
.scroll-button {
|
||||
.icon {
|
||||
fill: var(--lighten);
|
||||
}
|
||||
|
||||
&.scroll-start .icon,
|
||||
&.scroll-end .icon {
|
||||
fill: var(--darken-weak);
|
||||
}
|
||||
|
||||
&:hover:not(.scroll-start):not(.scroll-end) .icon {
|
||||
fill: var(--text-light);
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-left {
|
||||
background: linear-gradient(to right, var(--profile) 50%, transparent);
|
||||
}
|
||||
|
||||
.scroll-right {
|
||||
background: linear-gradient(to left, var(--profile) 50%, transparent);
|
||||
}
|
||||
|
||||
.expand-light {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-button {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
&.scroll-start,
|
||||
&.scroll-end {
|
||||
/* use over v-show so button stays visible while still hovered */
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-left {
|
||||
left: 0;
|
||||
padding: 1rem 2rem 1rem 1rem;
|
||||
}
|
||||
|
||||
.scroll-right {
|
||||
right: 0;
|
||||
padding: 1rem 1rem 1rem 2rem;
|
||||
}
|
||||
|
||||
@media(max-width: $breakpoint) {
|
||||
.scroll-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user