fix: hover transition animation and background color

This commit is contained in:
Rizumu Ayaka
2026-02-03 19:34:15 +08:00
parent 4b649d482a
commit 416bff2dc7
2 changed files with 36 additions and 8 deletions

View File

@@ -1,11 +1,28 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { nextTick } from 'vue'
import { describe, expect, it, vi } from 'vitest'
import { nextTick, ref } from 'vue'
import VirtualGrid from './VirtualGrid.vue'
type TestItem = { key: string; name: string }
const mockedWidth = ref(400)
const mockedHeight = ref(200)
const mockedScrollY = ref(0)
// VirtualGrid uses element size + scroll position to decide which items to render.
// In Vitest's happy-dom environment these measurements are often `0`, making the
// component render nothing and causing flaky tests. Mock vueuse so the
// virtualization window is deterministic for unit tests.
vi.mock('@vueuse/core', async () => {
const actual = await vi.importActual<Record<string, unknown>>('@vueuse/core')
return {
...actual,
useElementSize: () => ({ width: mockedWidth, height: mockedHeight }),
useScroll: () => ({ y: mockedScrollY })
}
})
function createItems(count: number): TestItem[] {
return Array.from({ length: count }, (_, i) => ({
key: `item-${i}`,
@@ -22,6 +39,10 @@ describe('VirtualGrid', () => {
it('renders items within the visible range', async () => {
const items = createItems(100)
mockedWidth.value = 400
mockedHeight.value = 200
mockedScrollY.value = 0
const wrapper = mount(VirtualGrid<TestItem>, {
props: {
items,
@@ -42,6 +63,7 @@ describe('VirtualGrid', () => {
await nextTick()
const renderedItems = wrapper.findAll('.test-item')
expect(renderedItems.length).toBeGreaterThan(0)
expect(renderedItems.length).toBeLessThan(items.length)
wrapper.unmount()
@@ -50,6 +72,9 @@ describe('VirtualGrid', () => {
it('provides correct index in slot props', async () => {
const items = createItems(20)
const receivedIndices: number[] = []
mockedWidth.value = 400
mockedHeight.value = 200
mockedScrollY.value = 0
const wrapper = mount(VirtualGrid<TestItem>, {
props: {
@@ -82,6 +107,10 @@ describe('VirtualGrid', () => {
it('respects maxColumns prop', async () => {
const items = createItems(10)
mockedWidth.value = 400
mockedHeight.value = 200
mockedScrollY.value = 0
const wrapper = mount(VirtualGrid<TestItem>, {
props: {
items,

View File

@@ -56,13 +56,12 @@ function handleVideoLoad(event: Event) {
<div
:class="
cn(
'flex gap-1 select-none group/item cursor-pointer bg-component-node-widget-background',
'transition-[transform,box-shadow,background-color] duration-150',
'flex gap-1 select-none group/item cursor-pointer transition-all duration-150',
{
'flex-col text-center': layout === 'grid',
'flex-row text-left max-h-16 rounded-lg hover:scale-102 active:scale-98':
'flex-col text-center rounded-sm': layout === 'grid',
'flex-row text-left max-h-16 rounded-lg bg-component-node-widget-background hover:scale-102 active:scale-98 hover:bg-component-node-widget-background-hovered':
layout === 'list',
'flex-row text-left hover:bg-component-node-widget-background-hovered rounded-lg':
'flex-row text-left rounded-lg bg-component-node-widget-background hover:bg-component-node-widget-background-hovered':
layout === 'list-small',
// selection
'ring-2 ring-component-node-widget-background-highlighted':
@@ -79,7 +78,7 @@ function handleVideoLoad(event: Event) {
cn(
'relative',
'w-full aspect-square overflow-hidden outline-1 outline-offset-[-1px] outline-interface-stroke',
'transition-[transform,box-shadow] duration-150',
'transition-all duration-150',
{
'min-w-16 max-w-16 rounded-l-lg': layout === 'list',
'rounded-sm group-hover/item:scale-108 group-active/item:scale-95':