Skip to content

Commit

Permalink
DESIGN-8 FixedVirtualList -> VirtualList (container 높이 제거)
Browse files Browse the repository at this point in the history
  • Loading branch information
baegofda committed Oct 23, 2024
1 parent 97ed1a4 commit 67ebec5
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,25 @@ import clsx from 'clsx';
import { Meta } from '@storybook/react';
import React, { memo, useEffect, useRef, useState } from 'react';

import { FixedVirtualListProps } from '@/core/components/Virtual/FixedVirtualList/types';
import FixedVirtualList from './index';
import VirtualList from './index';
import { VirtualListProps } from '@/core/components/Virtual/VirtualList/types';

const meta = {
title: 'core/Virtual/FixedVirtualList',
component: FixedVirtualList,
title: 'core/Virtual/VirtualList',
component: VirtualList,
argTypes: {
itemHeight: {
control: 'number',
description: 'FixedVirtualList item Height',
},
containerHeight: {
control: 'number',
description: 'FixedVirtualList container Height',
description: 'VirtualList item Height',
},
},
} satisfies Meta<typeof FixedVirtualList>;
} satisfies Meta<typeof VirtualList>;

export default meta;

export const Default = ({
itemHeight = 90,
containerHeight = 500,
}: Pick<FixedVirtualListProps, 'itemHeight' | 'containerHeight'>) => {
}: Pick<VirtualListProps, 'itemHeight'>) => {
const listRef = useRef<HTMLUListElement | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [images, setImages] = useState<
Expand Down Expand Up @@ -72,22 +67,21 @@ export const Default = ({
};

return (
<>
<div className={'flex-v-stack h-[500px]'}>
<input onChange={onChange} />
<FixedVirtualList
<VirtualList
listElement={'ul'}
itemHeight={itemHeight}
containerHeight={containerHeight}
itemsTotalCount={itemsTotalCount}
className={'w-[500px] bg-gray-02'}
className={'bg-gray-02'}
ref={listRef}
>
{({ startIndex, endIndex, getTopPosition }) =>
images.slice(startIndex, endIndex).map((image, index) => {
const { id, author, download_url } = image;

return (
<FixedVirtualList.Item
<VirtualList.Item
key={id}
element={'li'}
topPosition={getTopPosition({ index })}
Expand All @@ -96,12 +90,12 @@ export const Default = ({
>
<ImageComponent key={download_url} src={download_url} />
<AuthorComponent key={author} author={author} />
</FixedVirtualList.Item>
</VirtualList.Item>
);
})
}
</FixedVirtualList>
</>
</VirtualList>
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { ElementType, memo, PropsWithChildren } from 'react';
import clsx from 'clsx';

import { FixedVirtualListItemProps } from '@/core/components/Virtual/FixedVirtualList/types';
import { VirtualListItemProps } from '@/core/components/Virtual/VirtualList/types';

const FixedVirtualListItem = <T extends ElementType = 'div'>({
const VirtualListItem = <T extends ElementType = 'div'>({
topPosition,
className,
element: Element,
children,
height,
}: PropsWithChildren<FixedVirtualListItemProps<T>>) => {
}: PropsWithChildren<VirtualListItemProps<T>>) => {
const Component: React.ElementType = Element || 'div';
const classNames = clsx(
'absolute left-0 right-0 top-0 flex items-center will-change-transform',
Expand All @@ -26,5 +26,4 @@ const FixedVirtualListItem = <T extends ElementType = 'div'>({
</Component>
);
};

export default memo(FixedVirtualListItem);
export default memo(VirtualListItem);
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import clsx from 'clsx';
import React, {
ElementType,
forwardRef,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import clsx from 'clsx';

import FixedVirtualListItem from '@/core/components/Virtual/FixedVirtualList/FixedVirtualListItem';
import {
FixedVirtualListProps,
GetTopPositionParams,
ReturnType,
} from '@/core/components/Virtual/FixedVirtualList/types';
VirtualListProps,
} from '@/core/components/Virtual/VirtualList/types';
import { mergeRefs } from '@/utilities/ref';
import VirtualListItem from '@/core/components/Virtual/VirtualList/VirtualListItem';

const FixedVirtualList = forwardRef<HTMLElement, FixedVirtualListProps>(
const VirtualList = forwardRef<HTMLElement, VirtualListProps>(
(
{
containerHeight,
itemHeight,
itemsTotalCount,
rootElement: RootElement,
Expand All @@ -30,6 +30,7 @@ const FixedVirtualList = forwardRef<HTMLElement, FixedVirtualListProps>(
) => {
const containerRef = useRef<HTMLElement | null>(null);
const [scrollTop, setScrollTop] = useState(0);
const [containerHeight, setContainerHeight] = useState(0);
const visibleCount = Math.ceil(containerHeight / itemHeight);
const totalItemsHeight = itemHeight * itemsTotalCount;
const classNames = clsx('overflow-y-auto', className);
Expand All @@ -52,14 +53,27 @@ const FixedVirtualList = forwardRef<HTMLElement, FixedVirtualListProps>(
[startIndex, itemHeight],
);

useEffect(() => {
const calculateContainerHeight = () => {
if (containerRef.current) {
setContainerHeight(containerRef.current.clientHeight);
}
};

calculateContainerHeight();

window.addEventListener('resize', calculateContainerHeight);

return () => {
window.removeEventListener('resize', calculateContainerHeight);
};
}, []);

return (
<RootComponent
ref={mergeRefs(containerRef, ref)}
className={classNames}
onScroll={handleScroll}
style={{
height: `${containerHeight}px`,
}}
>
<ListComponent
className={'relative'}
Expand All @@ -76,7 +90,7 @@ const FixedVirtualList = forwardRef<HTMLElement, FixedVirtualListProps>(
},
) as unknown as ReturnType;

FixedVirtualList.displayName = 'FixedVirtualList';
FixedVirtualList.Item = FixedVirtualListItem;
VirtualList.displayName = 'VirtualList';
VirtualList.Item = VirtualListItem;

export default FixedVirtualList;
export default VirtualList;
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import {
RefAttributes,
} from 'react';

import FixedVirtualListItem from '@/core/components/Virtual/FixedVirtualList/FixedVirtualListItem';
import VirtualListItem from '@/core/components/Virtual/VirtualList/VirtualListItem';

export interface FixedVirtualChildrenProps {
export interface VirtualListChildrenProps {
startIndex: number;
endIndex: number;
getTopPosition: ({ index }: GetTopPositionParams) => string;
Expand All @@ -18,11 +18,10 @@ export interface GetTopPositionParams {
index: number;
}

export interface FixedVirtualListProps<
export interface VirtualListProps<
T extends ElementType = 'div',
P extends ElementType = 'div',
> extends Pick<HTMLAttributes<HTMLElement>, 'className'> {
containerHeight: number;
itemHeight: number;
itemsTotalCount: number;
rootElement?: T;
Expand All @@ -31,21 +30,21 @@ export interface FixedVirtualListProps<
startIndex,
endIndex,
getTopPosition,
}: FixedVirtualChildrenProps) => ReactNode;
}: VirtualListChildrenProps) => ReactNode;
}

export interface FixedVirtualListItemProps<T extends ElementType = 'div'>
export interface VirtualListItemProps<T extends ElementType = 'div'>
extends Pick<HTMLAttributes<HTMLElement>, 'className'> {
element?: T;
topPosition: string;
height: number;
}

export type FixedVirtualListComponent = ForwardRefExoticComponent<
FixedVirtualListProps<ElementType, ElementType> & RefAttributes<HTMLElement>
export type VirtualListItemComponent = ForwardRefExoticComponent<
VirtualListProps<ElementType, ElementType> & RefAttributes<HTMLElement>
>;

export type ReturnType = FixedVirtualListComponent & {
export type ReturnType = VirtualListItemComponent & {
displayName: string;
Item: typeof FixedVirtualListItem;
Item: typeof VirtualListItem;
};
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export { default as DropdownBase } from '@/core/components/Dropdown/DropdownBase
export { default as DropdownBaseItem } from '@/core/components/Dropdown/DropdownBase/DropdownItem';
export { default as DropdownBaseItems } from '@/core/components/Dropdown/DropdownBase/DropdownItems';
export { default as DropdownBaseTrigger } from '@/core/components/Dropdown/DropdownBase/DropdownTrigger';
export { default as FixedVirtualList } from '@/core/components/Virtual/FixedVirtualList';
export { default as FixedVirtualListItem } from '@/core/components/Virtual/FixedVirtualList/FixedVirtualListItem';
export { default as VirtualList } from '@/core/components/Virtual/VirtualList';
export { default as VirtualListItem } from '@/core/components/Virtual/VirtualList/VirtualListItem';
export { default as DropdownFilter } from '@/core/components/Dropdown/DropdownFilter';
export { default as DropdownFilterItem } from '@/core/components/Dropdown/DropdownFilter/DropdownFilterItem';
export { default as DropdownFilterItems } from '@/core/components/Dropdown/DropdownFilter/DropdownFilterItems';
Expand Down Expand Up @@ -55,6 +55,7 @@ export { default as Tooltip } from '@/core/components/Tooltip';
export { default as Typography } from '@/core/components/Typography';
export { default as Chip } from '@/core/components/Chip';
export { default as Chips } from '@/core/components/Chips';
export * from '@/utilities/day';

export { useInput } from '@/core/components/Input/hooks/useInput';
export * from '@/utilities/day';
export * from '@/utilities/ref';

0 comments on commit 67ebec5

Please sign in to comment.