Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(deps): upgrade @tanstack/react-virtual to v3.11.2 #8062

Merged
merged 2 commits into from
Dec 17, 2024
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 @@ -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.

Loading