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