Skip to content

Commit

Permalink
feat(useList): redesigned api (#1661)
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaevAlexandr authored Jun 21, 2024
1 parent e9e2383 commit ea320f7
Show file tree
Hide file tree
Showing 75 changed files with 1,846 additions and 2,433 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine

const dndRenderContainer: TreeSelectRenderContainer<TableColumnSetupItem> = ({
renderItem,
visibleFlattenIds,
itemsById,
list,
containerRef,
id,
className,
Expand All @@ -126,15 +125,15 @@ const useDndRenderContainer = ({onDragEnd, renderControls}: UseDndRenderContaine
};

return renderItem(
visibleFlattenIds[rubric.source.index],
list.structure.visibleFlattenIds[rubric.source.index],
rubric.source.index,
renderContainerProps,
);
};

const {stickyStartItemIdList, sortableItemIdList, stickyEndItemIdList} = prepareStickyState(
itemsById,
visibleFlattenIds,
list.structure.itemsById,
list.structure.visibleFlattenIds,
);

const stickyStartItemList = stickyStartItemIdList.map((visibleFlattenId, idx) => {
Expand Down
121 changes: 35 additions & 86 deletions src/components/TreeList/TreeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,107 +3,65 @@
import React from 'react';

import {useUniqId} from '../../hooks';
import {ListItemView, getItemRenderState, useList, useListKeydown} from '../useList';
import type {ListItemId} from '../useList';
import {
ListContainer,
ListItemView,
getItemRenderState,
getListItemClickHandler,
useListKeydown,
} from '../useList';
import type {ListOnItemClick} from '../useList';
import {block} from '../utils/cn';

import {TreeListContainer} from './components/TreeListContainer/TreeListContainer';
import type {TreeListProps, TreeListRenderContainerProps} from './types';
import type {TreeListContainerProps, TreeListProps} from './types';

const b = block('tree-list');

export const TreeList = <T,>({
qa,
id,
size = 'm',
items,
className,
expandedById: propsExpandedById,
disabledById: propsDisabledById,
selectedById: propsSelectedById,
activeItemId,
defaultGroupsExpanded = true,
getItemId,
renderItem: propsRenderItem,
renderContainer = TreeListContainer,
onItemClick,
list,
multiple,
setActiveItemId,
containerRef: propsContainerRef,
renderItem: propsRenderItem,
renderContainer = ListContainer,
onItemClick: propsOnItemClick,
mapItemDataToProps,
}: TreeListProps<T>) => {
const uniqId = useUniqId();
const treeListId = id ?? uniqId;
const containerRefLocal = React.useRef<HTMLDivElement>(null);
const containerRef = propsContainerRef ?? containerRefLocal;

const listParsedState = useList({
items,
getItemId,
// used not all of all properties but it may be needed in future
expandedById: propsExpandedById,
disabledById: propsDisabledById,
selectedById: propsSelectedById,
activeItemId,
});
const onItemClick = React.useMemo(() => {
if (propsOnItemClick === null) {
return undefined;
}

const expandedById = propsExpandedById || listParsedState.initialState.expandedById;
const disabledById = propsDisabledById || listParsedState.initialState.disabledById;
const selectedById = propsSelectedById || listParsedState.initialState.selectedById;
const handler: ListOnItemClick = (arg, e) => {
const payload = {id: arg.id, list};

const handleItemClick = React.useMemo(() => {
if (onItemClick) {
return (listItemId: ListItemId) => {
onItemClick?.({
id: listItemId,
index: listParsedState.idToFlattenIndex[listItemId],
data: listParsedState.itemsById[listItemId],
expanded:
// eslint-disable-next-line no-nested-ternary
expandedById && listItemId in expandedById
? expandedById[listItemId]
: listItemId in listParsedState.initialState.expandedById
? listParsedState.initialState.expandedById[listItemId]
: defaultGroupsExpanded,
disabled: disabledById
? Boolean(disabledById[listItemId])
: Boolean(listParsedState.initialState.disabledById[listItemId]),
selected: selectedById
? Boolean(selectedById[listItemId])
: Boolean(listParsedState.initialState.selectedById[listItemId]),
if (propsOnItemClick) {
propsOnItemClick?.(payload, e);
} else {
const baseOnClick = getListItemClickHandler({list, multiple});

context: {
isLastItem:
listParsedState.visibleFlattenIds[
listParsedState.visibleFlattenIds.length - 1
] === listItemId,
groupState: listParsedState.groupsState[listItemId],
itemState: listParsedState.itemsState[listItemId],
},
});
};
}
baseOnClick(payload, e);
}
};

return undefined;
}, [
defaultGroupsExpanded,
disabledById,
expandedById,
selectedById,
listParsedState,
onItemClick,
]);
return handler;
}, [propsOnItemClick, list, multiple]);

useListKeydown({
containerRef,
onItemClick: handleItemClick,
...listParsedState,
activeItemId,
disabledById,
setActiveItemId,
onItemClick,
list,
});

const renderItem: TreeListRenderContainerProps<T>['renderItem'] = (
const renderItem: TreeListContainerProps<T>['renderItem'] = (
itemId,
index,
renderContainerProps,
Expand All @@ -114,13 +72,8 @@ export const TreeList = <T,>({
size,
multiple,
mapItemDataToProps,
onItemClick: handleItemClick,
...listParsedState,
expandedById,
disabledById,
activeItemId,
selectedById,
defaultExpanded: defaultGroupsExpanded,
onItemClick,
list,
});

if (propsRenderItem) {
Expand All @@ -130,6 +83,7 @@ export const TreeList = <T,>({
context: renderState.context,
index,
renderContainerProps,
list,
});
}

Expand All @@ -143,12 +97,7 @@ export const TreeList = <T,>({
size,
containerRef,
className: b(null, className),
...listParsedState,
expandedById,
disabledById,
activeItemId,
selectedById,
list,
renderItem,
getItemId,
});
};
7 changes: 7 additions & 0 deletions src/components/TreeList/__stories__/Docs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {Meta, Markdown} from '@storybook/addon-docs';

import TreeListDocs from './TreeListDocs.md?raw';

<Meta title="Lab/TreeList" />

<Markdown>{TreeListDocs}</Markdown>
Loading

0 comments on commit ea320f7

Please sign in to comment.