mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-31 13:29:55 +00:00
Allow rectangular virtual grid items (#3093)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div ref="container" class="scroll-container">
|
||||
<div :style="{ height: `${(state.start / cols) * itemSize}px` }" />
|
||||
<div :style="{ height: `${(state.start / cols) * itemHeight}px` }" />
|
||||
<div :style="gridStyle">
|
||||
<div v-for="item in renderedItems" :key="item.key" data-virtual-grid-item>
|
||||
<slot name="item" :item="item"> </slot>
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div
|
||||
:style="{
|
||||
height: `${((props.items.length - state.end) / cols) * itemSize}px`
|
||||
height: `${((items.length - state.end) / cols) * itemHeight}px`
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
@@ -19,22 +19,25 @@ import { useElementSize, useScroll } from '@vueuse/core'
|
||||
import { clamp, debounce } from 'lodash'
|
||||
import { type CSSProperties, computed, onBeforeUnmount, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
const {
|
||||
items,
|
||||
bufferRows = 1,
|
||||
scrollThrottle = 64,
|
||||
resizeDebounce = 64,
|
||||
defaultItemHeight = 200,
|
||||
defaultItemWidth = 200
|
||||
} = defineProps<{
|
||||
items: (T & { key: string })[]
|
||||
gridStyle: Partial<CSSProperties>
|
||||
bufferRows?: number
|
||||
scrollThrottle?: number
|
||||
resizeDebounce?: number
|
||||
defaultItemSize?: number
|
||||
defaultItemHeight?: number
|
||||
defaultItemWidth?: number
|
||||
}>()
|
||||
const {
|
||||
bufferRows = 1,
|
||||
scrollThrottle = 64,
|
||||
resizeDebounce = 64,
|
||||
defaultItemSize = 200
|
||||
} = props
|
||||
|
||||
const itemSize = ref(defaultItemSize)
|
||||
const itemHeight = ref(defaultItemHeight)
|
||||
const itemWidth = ref(defaultItemWidth)
|
||||
const container = ref<HTMLElement | null>(null)
|
||||
const { width, height } = useElementSize(container)
|
||||
const { y: scrollY } = useScroll(container, {
|
||||
@@ -42,12 +45,10 @@ const { y: scrollY } = useScroll(container, {
|
||||
eventListenerOptions: { passive: true }
|
||||
})
|
||||
|
||||
const cols = computed(() => Math.floor(width.value / itemSize.value) || 1)
|
||||
const viewRows = computed(() => Math.ceil(height.value / itemSize.value))
|
||||
const offsetRows = computed(() => Math.floor(scrollY.value / itemSize.value))
|
||||
const isValidGrid = computed(
|
||||
() => height.value && width.value && props.items?.length
|
||||
)
|
||||
const cols = computed(() => Math.floor(width.value / itemWidth.value) || 1)
|
||||
const viewRows = computed(() => Math.ceil(height.value / itemHeight.value))
|
||||
const offsetRows = computed(() => Math.floor(scrollY.value / itemHeight.value))
|
||||
const isValidGrid = computed(() => height.value && width.value && items?.length)
|
||||
|
||||
const state = computed<{ start: number; end: number }>(() => {
|
||||
const fromRow = offsetRows.value - bufferRows
|
||||
@@ -57,18 +58,19 @@ const state = computed<{ start: number; end: number }>(() => {
|
||||
const toCol = toRow * cols.value
|
||||
|
||||
return {
|
||||
start: clamp(fromCol, 0, props.items?.length),
|
||||
end: clamp(toCol, fromCol, props.items?.length)
|
||||
start: clamp(fromCol, 0, items?.length),
|
||||
end: clamp(toCol, fromCol, items?.length)
|
||||
}
|
||||
})
|
||||
const renderedItems = computed(() =>
|
||||
isValidGrid.value ? props.items.slice(state.value.start, state.value.end) : []
|
||||
isValidGrid.value ? items.slice(state.value.start, state.value.end) : []
|
||||
)
|
||||
|
||||
const updateItemSize = () => {
|
||||
if (container.value) {
|
||||
const firstItem = container.value.querySelector('[data-virtual-grid-item]')
|
||||
itemSize.value = firstItem?.clientHeight || defaultItemSize
|
||||
itemHeight.value = firstItem?.clientHeight || defaultItemHeight
|
||||
itemWidth.value = firstItem?.clientWidth || defaultItemWidth
|
||||
}
|
||||
}
|
||||
const onResize = debounce(updateItemSize, resizeDebounce)
|
||||
|
||||
Reference in New Issue
Block a user