Skip to content

Commit

Permalink
refactor(@clayui/core): uses the Collection component for the TreeView
Browse files Browse the repository at this point in the history
  • Loading branch information
matuzalemsteles committed Aug 24, 2022
1 parent 312e1a8 commit 9b5f144
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 68 deletions.
97 changes: 32 additions & 65 deletions packages/clay-core/src/tree-view/Collection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@

import React from 'react';

import {
ChildrenFunction as ChildrenFunctionBase,
Collection as CollectionBase,
excludeProps,
} from '../collection';
import {Expand, Selection, useAPI} from './context';
import {ItemContextProvider, useItem} from './useItem';

export type ChildrenFunction<T> = (
item: Omit<T, 'index' | 'indexes' | 'itemRef' | 'key' | 'parentItemRef'>,
selection: Selection,
expand: Expand
) => React.ReactElement;
export type ChildrenFunction<T extends Record<string, any>> =
ChildrenFunctionBase<T, [Selection, Expand]>;

export interface ICollectionProps<T> {
children: React.ReactNode | ChildrenFunction<T>;
Expand All @@ -28,72 +30,37 @@ export interface ICollectionProps<T> {
items?: Array<T>;
}

export function getKey(
index: number,
key?: React.Key | null,
parentKey?: React.Key
) {
if (
key != null &&
(!String(key).startsWith('.') || String(key).startsWith('.$'))
) {
return key;
}
const exclude = new Set([
'index',
'indexes',
'itemRef',
'key',
'parentItemRef',
]);

return parentKey ? `${parentKey}.${index}` : `$.${index}`;
}

export function removeItemInternalProps<T extends Record<any, any>>(props: T) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {index, indexes, itemRef, key, parentItemRef, ...item} = props;

return item;
}

export function Collection<T extends Record<any, any>>({
export function Collection<T extends Record<string, any>>({
children,
items,
}: ICollectionProps<T>) {
const api = useAPI();
const {key: parentKey} = useItem();

return (
<>
{typeof children === 'function' && items
? items.map((item, index) => {
const child = children(
removeItemInternalProps(item),
...api
);

const key = getKey(
index,
item.id ?? child.key,
parentKey
);

return (
<ItemContextProvider
key={key}
value={{...item, index, key}}
>
{child}
</ItemContextProvider>
);
})
: React.Children.map(children, (child, index) => {
if (!React.isValidElement(child)) {
return null;
}

const key = getKey(index, child.key, parentKey);

return (
<ItemContextProvider key={key} value={{index, key}}>
{child}
</ItemContextProvider>
);
})}
</>
<CollectionBase
exclude={exclude}
itemContainer={({item = {}, index, keyValue, children}) => (
<ItemContextProvider value={{...item, index, key: keyValue}}>
{children}
</ItemContextProvider>
)}
items={items}
parentKey={parentKey}
publicApi={useAPI()}
>
{children}
</CollectionBase>
);
}

export function removeItemInternalProps<T extends Record<any, any>>(props: T) {
return excludeProps(props, exclude);
}
4 changes: 2 additions & 2 deletions packages/clay-core/src/tree-view/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export type Expand = {
has: (key: Key) => boolean;
};

export function useAPI() {
export function useAPI(): [Selection, Expand] {
const {expandedKeys, selection, toggle} = useTreeViewContext();

const hasKey = useCallback(
Expand All @@ -69,5 +69,5 @@ export function useAPI() {
toggle: selection.toggleSelection,
},
{has: hasExpandedKey, toggle},
] as const;
];
}
2 changes: 1 addition & 1 deletion packages/clay-core/src/tree-view/useMultipleSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import {useInternalState} from '@clayui/shared';
import {Key, useCallback, useMemo, useRef} from 'react';

import {getKey} from './Collection';
import {getKey} from '../collection';
import {ITreeProps, createImmutableTree} from './useTree';

import type {ICollectionProps} from './Collection';
Expand Down

0 comments on commit 9b5f144

Please sign in to comment.