Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/sanity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
"@sanity/uuid": "^3.0.3",
"@sanity/validation": "workspace:*",
"@sentry/react": "^11.8.0",
"@tanstack/react-virtual": "^3.14.19",
"@tanstack/react-virtual": "^3.14.21",
"@xstate/react": "^6.1.0",
"clsx": "^2.1.1",
"color2k": "^2.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import {studioTheme, ThemeProvider} from '@sanity/ui'
import {render, screen, waitFor} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {useCallback} from 'react'
import {beforeEach, describe, expect, it} from 'vitest'
import {describe, expect, it} from 'vitest'

import {setupVirtualListEnv} from '../../../../../test/testUtils/setupVirtualListEnv'
import {CommandList} from '../CommandList'

const COMMAND_LIST_TEST_ID = 'command-list'
Expand Down Expand Up @@ -62,41 +63,7 @@ function TestComponent(props: TestComponentProps) {
}

describe('core/components: CommandList', () => {
beforeEach(() => {
const originalOffsetHeight = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetHeight',
)
const originalOffsetWidth = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetWidth',
)
// Virtual list will return an empty list of items unless we have some size,
// so we need to mock offsetHeight and offsetWidth to return a size for the list.
// Not pretty, but it's what they recommend for testing outside of browsers:
// https://github.com/TanStack/virtual/issues/641
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
get() {
return 800
},
})
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
configurable: true,
get() {
return 800
},
})

return () => {
if (originalOffsetHeight) {
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', originalOffsetHeight)
}
if (originalOffsetWidth) {
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', originalOffsetWidth)
}
}
})
setupVirtualListEnv(undefined, 800, 800)

it('should change active item on pressing arrow keys', async () => {
render(<TestComponent items={[0, 1, 2, 3]} />)
Expand Down
64 changes: 30 additions & 34 deletions packages/sanity/test/testUtils/setupVirtualListEnv.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,44 @@
import {beforeEach, vi} from 'vitest'

// jsdom has no layout engine, so every element dimension reads 0 and a virtualizer renders no
// items. Stub the dimensions the virtualizer reads, for the scroll element only when a test id is
// given. `@tanstack/virtual-core` measures the viewport with `clientWidth` / `clientHeight`
// (excluding borders and scrollbars, since 3.19.6) and each row with `offsetWidth` /
// `offsetHeight`, so both pairs are stubbed. Not pretty, but it's what they recommend for
// testing outside of browsers: https://github.com/TanStack/virtual/issues/641
const SIZE_PROPERTIES = ['offsetHeight', 'offsetWidth', 'clientHeight', 'clientWidth'] as const

export const setupVirtualListEnv = (
dataTestId?: string,
rectWidth: number = 350,
rectHeight: number = 800,
) => {
beforeEach(() => {
const originalOffsetHeight = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetHeight',
)
const originalOffsetWidth = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetWidth',
const originalDescriptors = SIZE_PROPERTIES.map(
(property) =>
[property, Object.getOwnPropertyDescriptor(HTMLElement.prototype, property)] as const,
)
// Virtual list will return an empty list of items unless we have some size,
// so we need to mock offsetHeight and offsetWidth to return a size for the list.
// Not pretty, but it's what they recommend for testing outside of browsers:
// https://github.com/TanStack/virtual/issues/641
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
get: vi.fn(function (this: Element) {
if (!dataTestId || this.getAttribute('data-testid') === dataTestId) {
return rectHeight
}
return 0
}),
})
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
configurable: true,
get: vi.fn(function (this: Element) {
if (!dataTestId || this.getAttribute('data-testid') === dataTestId) {
return rectWidth
}
return 0
}),
})

for (const property of SIZE_PROPERTIES) {
const size = property.endsWith('Height') ? rectHeight : rectWidth
Object.defineProperty(HTMLElement.prototype, property, {
configurable: true,
get: vi.fn(function (this: Element) {
if (!dataTestId || this.getAttribute('data-testid') === dataTestId) {
return size
}
return 0
}),
})
}

return () => {
if (originalOffsetHeight) {
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', originalOffsetHeight)
}
if (originalOffsetWidth) {
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', originalOffsetWidth)
for (const [property, descriptor] of originalDescriptors) {
if (descriptor) {
Object.defineProperty(HTMLElement.prototype, property, descriptor)
} else {
delete (HTMLElement.prototype as Partial<HTMLElement>)[property]
}
}
}
})
Expand Down
18 changes: 9 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ minimumReleaseAgeExclude:
- '@vanilla-extract/*'
- '@vercel/stega'
- '@yuku-toolchain/*'
- '@tanstack/react-virtual@3.14.19'
- '@tanstack/virtual-core@3.19.4'
- '@codemirror/search'
- '@codemirror/state'
- '@codemirror/view'
Expand Down
Loading