Skip to content

Commit

Permalink
fix(deps): upgrade @tanstack/react-virtual to v3.11.2 (#8062)
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars authored Dec 17, 2024
1 parent cb1647b commit 04303f7
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 23 deletions.
2 changes: 1 addition & 1 deletion packages/sanity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
"@sanity/uuid": "^3.0.1",
"@sentry/react": "^8.33.0",
"@tanstack/react-table": "^8.16.0",
"@tanstack/react-virtual": "3.0.0-beta.54",
"@tanstack/react-virtual": "^3.11.2",
"@types/react-is": "^18.3.0",
"@types/shallow-equals": "^1.0.0",
"@types/speakingurl": "^13.0.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ const CommandListComponent = forwardRef<CommandListHandle, CommandListProps>(fun
onlyShowSelectionWhenActive,
overscan,
renderItem,
testId,
wrapAround = true,
...responsivePaddingProps
},
Expand Down Expand Up @@ -583,6 +584,7 @@ const CommandListComponent = forwardRef<CommandListHandle, CommandListProps>(fun
ref={setVirtualListElement}
sizing="border"
tabIndex={rootTabIndex}
data-testid={testId}
{...responsivePaddingProps}
>
{canReceiveFocus && <FocusOverlayDiv offset={focusRingOffset} />}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {afterEach} from 'node:test'

import {studioTheme, ThemeProvider} from '@sanity/ui'
import {render, screen} from '@testing-library/react'
import {render, screen, waitFor} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {useCallback} from 'react'
import {describe, expect, it} from 'vitest'
import {beforeEach, describe, expect, it, vi} from 'vitest'

import {CommandList} from '../CommandList'

const COMMAND_LIST_TEST_ID = 'command-list'
const CUSTOM_ACTIVE_ATTR = 'my-active-data-attribute'

type Item = number
Expand Down Expand Up @@ -52,20 +55,52 @@ function TestComponent(props: TestComponentProps) {
// same as the number of items for the tests to pass
overscan={items.length}
renderItem={renderItem}
testId={COMMAND_LIST_TEST_ID}
/>
</div>
</ThemeProvider>
)
}

describe('core/components: CommandList', () => {
it('should change active item on pressing arrow keys', () => {
const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect

const getDOMRect = (width: number, height: number) => ({
width,
height,
top: 0,
left: 0,
bottom: 0,
right: 0,
x: 0,
y: 0,
toJSON: () => {},
})

beforeEach(() => {
// Virtual list will return an empty list of items unless we have some size,
// so we need to mock getBoundingClientRect 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
Element.prototype.getBoundingClientRect = vi.fn(function (this: Element) {
if (this.getAttribute('data-testid') === COMMAND_LIST_TEST_ID) {
return getDOMRect(350, 800)
}
return getDOMRect(0, 0)
})
})

afterEach(() => {
Element.prototype.getBoundingClientRect = originalGetBoundingClientRect
})

it('should change active item on pressing arrow keys', async () => {
render(<TestComponent items={[0, 1, 2, 3]} />)

const buttons = screen.getAllByTestId('button')

// First button should be active on render
expect(buttons[0]).toHaveAttribute(CUSTOM_ACTIVE_ATTR)
await waitFor(() => expect(buttons[0]).toHaveAttribute(CUSTOM_ACTIVE_ATTR))

// Set second button as active on arrow down
userEvent.keyboard('[ArrowDown]')
Expand Down Expand Up @@ -96,13 +131,13 @@ describe('core/components: CommandList', () => {
expect(buttons[3]).not.toHaveAttribute(CUSTOM_ACTIVE_ATTR)
})

it('should set the initial active item based on the initialIndex prop', () => {
it('should set the initial active item based on the initialIndex prop', async () => {
render(<TestComponent initialIndex={2} items={[0, 1, 3, 4]} />)

const buttons = screen.getAllByTestId('button')

// Button with index 2 should be active on render
expect(buttons[0]).not.toHaveAttribute(CUSTOM_ACTIVE_ATTR)
await waitFor(() => expect(buttons[0]).not.toHaveAttribute(CUSTOM_ACTIVE_ATTR))
expect(buttons[1]).not.toHaveAttribute(CUSTOM_ACTIVE_ATTR)
expect(buttons[2]).toHaveAttribute(CUSTOM_ACTIVE_ATTR)
expect(buttons[3]).not.toHaveAttribute(CUSTOM_ACTIVE_ATTR)
Expand All @@ -123,13 +158,13 @@ describe('core/components: CommandList', () => {
expect(buttons[0]).toHaveAttribute(CUSTOM_ACTIVE_ATTR)
})

it('should skip disabled elements', () => {
it('should skip disabled elements', async () => {
render(<TestComponent items={[0, 1, 2, 3]} withDisabledItems />)

const buttons = screen.getAllByTestId('button')

// Second button should be active since the first button is disabled
expect(buttons[1]).toHaveAttribute(CUSTOM_ACTIVE_ATTR)
await waitFor(() => expect(buttons[1]).toHaveAttribute(CUSTOM_ACTIVE_ATTR))

// Fourth button should be active since the third is disabled
userEvent.keyboard('[ArrowDown]')
Expand Down
2 changes: 2 additions & 0 deletions packages/sanity/src/core/components/commandList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ export interface CommandListProps<T = any> extends ResponsivePaddingProps {
overscan?: number
/** Rendered component in virtual lists */
renderItem: CommandListRenderItemCallback<T>
/** `data-testid` to apply to outermost container */
testId?: string
/** Allow wraparound keyboard navigation between first and last items */
wrapAround?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export function ListArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInp
elementProps,
members,
onChange,
onInsert,
onItemMove,
onUpload,
focusPath,
Expand Down Expand Up @@ -113,7 +112,7 @@ export function ListArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInp

const scroll = instance.scrollElement

const handleScroll = () => {
const handleScroll = (evt?: Event) => {
const containerElementTop = containerElement.current?.getBoundingClientRect().top ?? 0
const parentElementTop = parentRef.current?.getBoundingClientRect().top ?? 0

Expand All @@ -122,7 +121,7 @@ export function ListArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInp
// We pass a component that we have more control over to avoid issues when wrapped in custom component
const itemOffset = Math.floor(parentElementTop - containerElementTop)

callback(scroll.scrollTop - itemOffset)
callback(scroll.scrollTop - itemOffset, Boolean(evt))
}

handleScroll()
Expand Down Expand Up @@ -225,7 +224,7 @@ export function ListArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInp
top: 0,
left: 0,
width: '100%',
transform: `translateY(${items[0].start}px)`,
transform: items.length > 0 ? `translateY(${items[0].start}px)` : undefined,
}}
>
{items.map((virtualRow) => {
Expand Down
22 changes: 12 additions & 10 deletions pnpm-lock.yaml

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

0 comments on commit 04303f7

Please # to comment.