refactor: maded fadedscrollablediv better
This commit is contained in:
parent
caefb0e2d3
commit
458b068748
@ -1,29 +1,75 @@
|
||||
<template>
|
||||
<div ref="scrollableDiv" class="scrr" :style="`maskImage: ${maskStyle}`">
|
||||
<div
|
||||
ref="scrollableDiv"
|
||||
:style="`maskImage: ${maskStyle}`"
|
||||
@scroll="updateMaskStyle"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
maskHeight: {
|
||||
maskLength: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
default: 30,
|
||||
},
|
||||
orientation: {
|
||||
type: String,
|
||||
default: 'vertical',
|
||||
},
|
||||
})
|
||||
|
||||
const scrollableDiv = ref(null)
|
||||
const maskStyle = ref('none')
|
||||
const side = computed(() =>
|
||||
props.orientation == 'horizontal' ? 'right' : 'bottom'
|
||||
)
|
||||
|
||||
function setMaskStyle() {
|
||||
// show mask only if div is scrollable
|
||||
if (scrollableDiv.value.scrollHeight > scrollableDiv.value.clientHeight) {
|
||||
maskStyle.value = `linear-gradient(to bottom, black calc(100% - ${props.maskHeight}px), transparent 100%);`
|
||||
} else {
|
||||
function updateMaskStyle() {
|
||||
if (!scrollableDiv.value) return
|
||||
|
||||
let scrollWidth = scrollableDiv.value.scrollWidth
|
||||
let clientWidth = scrollableDiv.value.clientWidth
|
||||
let scrollHeight = scrollableDiv.value.scrollHeight
|
||||
let clientHeight = scrollableDiv.value.clientHeight
|
||||
let scrollTop = scrollableDiv.value.scrollTop
|
||||
let scrollLeft = scrollableDiv.value.scrollLeft
|
||||
|
||||
maskStyle.value = 'none'
|
||||
|
||||
// faded on both sides
|
||||
if (
|
||||
(side.value == 'right' && scrollWidth > clientWidth) ||
|
||||
(side.value == 'bottom' && scrollHeight > clientHeight)
|
||||
) {
|
||||
maskStyle.value = `linear-gradient(to ${side.value}, transparent, black ${props.maskLength}px, black calc(100% - ${props.maskLength}px), transparent);`
|
||||
}
|
||||
|
||||
// faded on left or top
|
||||
if (
|
||||
(side.value == 'right' && scrollLeft - 20 > clientWidth) ||
|
||||
(side.value == 'bottom' && scrollTop + clientHeight >= scrollHeight)
|
||||
) {
|
||||
maskStyle.value = `linear-gradient(to ${side.value}, transparent, black ${props.maskLength}px, black 100%, transparent);`
|
||||
}
|
||||
|
||||
// faded on right or bottom
|
||||
if (
|
||||
(side.value == 'right' && scrollLeft == 0) ||
|
||||
(side.value == 'bottom' && scrollTop == 0)
|
||||
) {
|
||||
maskStyle.value = `linear-gradient(to ${side.value}, black calc(100% - ${props.maskLength}px), transparent 100%);`
|
||||
}
|
||||
|
||||
if (
|
||||
(side.value == 'right' && clientWidth == scrollWidth) ||
|
||||
(side.value == 'bottom' && clientHeight == scrollHeight)
|
||||
) {
|
||||
maskStyle.value = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => setMaskStyle())
|
||||
onMounted(() => setTimeout(() => updateMaskStyle(), 300))
|
||||
</script>
|
||||
|
||||
@ -23,15 +23,9 @@
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div class="-mr-2 h-[70%] border-l" />
|
||||
<div
|
||||
<FadedScrollableDiv
|
||||
class="flex flex-1 items-center overflow-x-auto px-1"
|
||||
style="
|
||||
mask-image: linear-gradient(
|
||||
to right,
|
||||
black calc(100% - 20px),
|
||||
transparent 100%
|
||||
);
|
||||
"
|
||||
orientation="horizontal"
|
||||
>
|
||||
<div
|
||||
v-for="filter in quickFilterList"
|
||||
@ -78,7 +72,7 @@
|
||||
@change.stop="applyQuickFilter(filter, $event.target.value)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</FadedScrollableDiv>
|
||||
<div class="-ml-2 h-[70%] border-l" />
|
||||
<div class="flex items-center gap-2">
|
||||
<div
|
||||
@ -200,6 +194,7 @@ import UnpinIcon from '@/components/Icons/UnpinIcon.vue'
|
||||
import ViewModal from '@/components/Modals/ViewModal.vue'
|
||||
import SortBy from '@/components/SortBy.vue'
|
||||
import Filter from '@/components/Filter.vue'
|
||||
import FadedScrollableDiv from '@/components/FadedScrollableDiv.vue'
|
||||
import ColumnSettings from '@/components/ColumnSettings.vue'
|
||||
import { globalStore } from '@/stores/global'
|
||||
import { viewsStore } from '@/stores/views'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user