Stop the library grid from fighting scroll-up by dropping content-visibility and matching virtual row height to the cards.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+21
-8
@@ -136,7 +136,7 @@
|
||||
<div
|
||||
v-else
|
||||
ref="scroller"
|
||||
class="mt-3 min-h-[24rem] flex-1 overflow-y-auto"
|
||||
class="mt-3 min-h-[24rem] flex-1 overflow-y-auto overscroll-y-contain [overflow-anchor:none]"
|
||||
@scroll="onScroll"
|
||||
>
|
||||
<div :style="{ height: `${gridHeight}px`, position: 'relative' }">
|
||||
@@ -210,7 +210,7 @@
|
||||
</section>
|
||||
|
||||
<aside
|
||||
class="glass overflow-y-auto p-4 sm:p-5"
|
||||
class="glass overflow-y-auto overscroll-y-contain [overflow-anchor:none] p-4 sm:p-5"
|
||||
:class="focused
|
||||
? 'fixed inset-0 z-[60] rounded-none lg:static lg:z-auto lg:h-full lg:w-[min(38rem,42vw)] lg:shrink-0 lg:rounded-3xl'
|
||||
: 'hidden w-full shrink-0 rounded-3xl lg:block lg:h-full lg:w-[22rem]'"
|
||||
@@ -453,8 +453,8 @@ import { clipSettingsRows, stillSettingsRows } from '~/utils/libraryGeneration'
|
||||
|
||||
const CARD_MIN = 156
|
||||
const GAP = 10
|
||||
const ROW_H = 248
|
||||
const BUFFER_ROWS = 3
|
||||
const CARD_CAPTION = 50
|
||||
const BUFFER_ROWS = 4
|
||||
const DRAG_MIME = 'application/x-aigen-library'
|
||||
const filterOptions = [
|
||||
{ id: 'all' as const, label: 'All' },
|
||||
@@ -555,11 +555,16 @@ const emptyLabel = computed(() => {
|
||||
return 'Nothing in this folder yet.'
|
||||
})
|
||||
const cols = computed(() => Math.max(2, Math.floor((viewportW.value + GAP) / (CARD_MIN + GAP))))
|
||||
const rowH = computed(() => {
|
||||
const width = Math.max(CARD_MIN, (viewportW.value - GAP * (cols.value - 1)) / cols.value)
|
||||
return Math.round(width * 5 / 4) + CARD_CAPTION
|
||||
})
|
||||
const rowStride = computed(() => rowH.value + GAP)
|
||||
const rowCount = computed(() => Math.ceil(entries.value.length / cols.value) || 0)
|
||||
const gridHeight = computed(() => rowCount.value * ROW_H + Math.max(0, rowCount.value - 1) * GAP)
|
||||
const startRow = computed(() => Math.max(0, Math.floor(scrollTop.value / (ROW_H + GAP)) - BUFFER_ROWS))
|
||||
const visibleRowCount = computed(() => Math.ceil(viewportH.value / (ROW_H + GAP)) + BUFFER_ROWS * 2)
|
||||
const offsetY = computed(() => startRow.value * (ROW_H + GAP))
|
||||
const gridHeight = computed(() => rowCount.value * rowH.value + Math.max(0, rowCount.value - 1) * GAP)
|
||||
const startRow = computed(() => Math.max(0, Math.floor(scrollTop.value / rowStride.value) - BUFFER_ROWS))
|
||||
const visibleRowCount = computed(() => Math.ceil(viewportH.value / rowStride.value) + BUFFER_ROWS * 2)
|
||||
const offsetY = computed(() => startRow.value * rowStride.value)
|
||||
const visibleEntries = computed(() => {
|
||||
const start = startRow.value * cols.value
|
||||
const end = start + visibleRowCount.value * cols.value
|
||||
@@ -1100,6 +1105,14 @@ watch([folderId, filter], () => {
|
||||
watch(search, () => {
|
||||
if (scroller.value) scroller.value.scrollTop = 0
|
||||
})
|
||||
watch([cols, rowH], ([nextCols, nextRowH], [prevCols, prevRowH]) => {
|
||||
const el = scroller.value
|
||||
if (!el || !prevRowH) return
|
||||
if (nextCols === prevCols && nextRowH === prevRowH) return
|
||||
const index = Math.floor(el.scrollTop / (prevRowH + GAP)) * prevCols
|
||||
el.scrollTop = Math.floor(index / nextCols) * (nextRowH + GAP)
|
||||
scrollTop.value = el.scrollTop
|
||||
})
|
||||
watch(focusedKey, (key) => {
|
||||
if (!key) {
|
||||
detailsHidden.value = false
|
||||
|
||||
Reference in New Issue
Block a user