Skip to content

Commit

Permalink
feat(Picker): removing tanstack virtualization
Browse files Browse the repository at this point in the history
  • Loading branch information
VadymBezpalko committed Dec 6, 2023
1 parent 5869151 commit 0ee2e37
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 103 deletions.
62 changes: 21 additions & 41 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions packages/react-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@
"@livechat/data-utils": "^0.2.16",
"@livechat/design-system-icons": "^1.6.1",
"@popperjs/core": "^2.11.2",
"@tanstack/react-virtual": "^3.0.0-beta.68",
"clsx": "^1.1.1",
"date-fns": "^2.28.0",
"lodash.debounce": "^4.0.8",
"lodash.escape": "^4.0.1",
"polished": "^4.1.3",
"react-day-picker": "^7.4.10",
"react-transition-group": "^4.4.2"
"react-transition-group": "^4.4.2",
"react-virtuoso": "^4.6.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ export const Picker: React.FC<IPickerProps> = ({
setFloating={refs.setFloating}
floatingStyles={floatingStyles}
maxHeight={maxHeight}
floatingRef={refs.floating}
isPositioned={isPositioned}
pointer={pointer}
activeIndex={activeIndex}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import * as React from 'react';

import { FloatingFocusManager, FloatingContext } from '@floating-ui/react';
import { useVirtualizer } from '@tanstack/react-virtual';
import cx from 'clsx';

import { ITEM_HEIGHT } from '../constants';
import { IPickerListItem } from '../types';

import { PickerListItem } from './PickerListItem';
Expand All @@ -18,7 +16,6 @@ interface IPickerListProps {
setFloating: (node: HTMLElement | null) => void;
floatingStyles: React.CSSProperties;
maxHeight: number;
floatingRef: React.MutableRefObject<HTMLElement | null>;
listElementsRef: React.MutableRefObject<(HTMLElement | null)[]>;
isPositioned: boolean;
pointer: boolean;
Expand All @@ -44,7 +41,6 @@ export const PickerList: React.FC<IPickerListProps> = ({
floatingStyles,
maxHeight,
options,
floatingRef,
isPositioned,
pointer,
activeIndex,
Expand All @@ -65,29 +61,11 @@ export const PickerList: React.FC<IPickerListProps> = ({
[styles[`${baseClass}__no-results`]]: options.length === 0,
});

const rowVirtualizer = useVirtualizer({
count: options.length,
getScrollElement: () => floatingRef.current,
estimateSize: () => ITEM_HEIGHT, // TODO for a custom element, we need to get the height of the custom element
overscan: 5,
getItemKey: (index) => options[index].key,
});

React.useLayoutEffect(() => {
if (isPositioned && !pointer) {
// Nothing has been selected, reset scrolling upon open
if (activeIndex === null && selectedKeys.length === 0) {
rowVirtualizer.scrollToIndex(0);
}

// Scrolling is restored, but the item will be scrolled
// into view when necessary
if (activeIndex !== null) {
wrapperRef.current?.focus({ preventScroll: true });
rowVirtualizer.scrollToIndex(activeIndex);
}
if (isPositioned && !pointer && activeIndex !== null) {
wrapperRef.current?.focus({ preventScroll: true });
}
}, [rowVirtualizer, isPositioned, activeIndex, pointer, wrapperRef]);
}, [isPositioned, activeIndex, pointer, wrapperRef]);

if (options.length === 0) {
return (
Expand Down Expand Up @@ -119,9 +97,6 @@ export const PickerList: React.FC<IPickerListProps> = ({
tabIndex={0}
aria-multiselectable={pickerType === 'multi'}
className={styles['listbox-wrapper']}
style={{
height: `${rowVirtualizer.getTotalSize()}px`,
}}
ref={wrapperRef}
// Some screen readers do not like any wrapper tags inside
// the element with the role, so we spread it onto the
Expand All @@ -148,15 +123,15 @@ export const PickerList: React.FC<IPickerListProps> = ({
},
})}
>
{rowVirtualizer.getVirtualItems().map((virtualItem) => (
{options.map((item, index) => (
<PickerListItem
virtualItem={virtualItem}
index={index}
getItemProps={getItemProps}
listElementsRef={listElementsRef}
isActive={activeIndex === virtualItem.index}
isSelected={selectedKeys.includes(virtualItem.key.toString())}
isActive={activeIndex === index}
isSelected={selectedKeys.includes(item.key)}
onSelect={handleSelect}
item={options[virtualItem.index]}
item={item}
numberOfItems={numberOfItems}
/>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ $base-class: 'picker-list';
&__item {
box-sizing: border-box;
display: flex;
position: absolute;
top: 0;
left: 0;
align-items: center;
justify-content: center;
margin-bottom: var(--spacing-05);
Expand Down Expand Up @@ -52,14 +49,14 @@ $base-class: 'picker-list';

&__header {
display: flex;
position: absolute;
top: 0;
left: 0;
position: relative;
align-items: center;
justify-content: space-between;
z-index: 1;
margin-bottom: var(--spacing-05);
background-color: var(--picker-list-group-background);
cursor: auto;
padding: 12px 12px 4px;
width: 100%;
height: 36px;
text-transform: uppercase;
color: var(--content-basic-secondary);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import * as React from 'react';

import { Check } from '@livechat/design-system-icons';
import { VirtualItem } from '@tanstack/react-virtual';
import cx from 'clsx';

import { Icon } from '../../Icon';
import { IPickerListItem } from '../../Picker';
import { ITEM_GAP_HEIGHT } from '../constants';

import styles from './PickerListItem.module.scss';

interface IPickerListItemProps {
virtualItem: VirtualItem;
index: number;
isActive: boolean;
isSelected: boolean;
numberOfItems: number;
Expand All @@ -26,7 +24,7 @@ interface IPickerListItemProps {
const itemClassName = `picker-list__item`;

export const PickerListItem: React.FC<IPickerListItemProps> = ({
virtualItem,
index,
isActive,
isSelected,
listElementsRef,
Expand Down Expand Up @@ -88,14 +86,10 @@ export const PickerListItem: React.FC<IPickerListItemProps> = ({
if (item.groupHeader) {
return (
<div
id={`item-${virtualItem.index}`}
key={virtualItem.key}
id={`item-${index}`}
key={item.key}
role="group"
className={styles[`${itemClassName}__header`]}
style={{
height: `${virtualItem.size}px`,
transform: `translateY(${virtualItem.start}px)`,
}}
{...getItemProps()}
>
{item.name}
Expand All @@ -109,27 +103,23 @@ export const PickerListItem: React.FC<IPickerListItemProps> = ({

return (
<div
id={`item-${virtualItem.index}`}
key={virtualItem.key}
id={`item-${index}`}
key={item.key}
tabIndex={isActive ? 0 : -1}
ref={(node) => {
listElementsRef.current[virtualItem.index] = node;
listElementsRef.current[index] = node;
}}
role="option"
aria-selected={isSelected}
aria-disabled={item.disabled}
aria-current={isActive}
aria-setsize={numberOfItems}
aria-posinset={virtualItem.index + 1}
aria-posinset={index + 1}
className={cx(styles[itemClassName], {
[styles[`${itemClassName}__custom`]]: item?.customElement,
})}
style={{
height: `${virtualItem.size - ITEM_GAP_HEIGHT}px`,
transform: `translateY(${virtualItem.start}px)`,
}}
{...getItemProps({
onClick: () => handleOnClick(virtualItem.key.toString()),
onClick: () => handleOnClick(item.key),
})}
>
<div className={styles[`${itemClassName}__content`]}>
Expand Down

0 comments on commit 0ee2e37

Please sign in to comment.