Skip to content

Commit

Permalink
fix(withTableSettings): fix selected item issue
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaevAlexandr committed Mar 18, 2024
1 parent bf07bdb commit dd736cc
Show file tree
Hide file tree
Showing 27 changed files with 129 additions and 147 deletions.
6 changes: 5 additions & 1 deletion src/components/Table/__stories__/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ const WithTableActionsTemplate: StoryFn<TableProps<DataItem>> = (args) => {
const items = ['action 1', 'action 2', 'action 3'];

return (
<TreeSelect items={items} size="s" getItemContent={(title) => ({title})} />
<TreeSelect
items={items}
size="s"
mapItemDataToProps={(title) => ({title})}
/>
);
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,4 @@ $block: '.#{variables.$ns}table-column-setup';
&__controls {
margin: var(--g-spacing-1) var(--g-spacing-1) 0;
}

// to override this https://github.com/gravity-ui/uikit/blob/main/src/components/useList/components/ListItemView/ListItemView.scss#L25
&__required-item {
background: inherit;

&:hover {
/* stylelint-disable declaration-no-important */
background: var(--g-color-base-simple-hover-solid) !important;
/* stylelint-enable declaration-no-important */
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,14 @@ import i18n from './i18n';

import './TableColumnSetup.scss';

const b = block('table-column-setup');
const tableColumnSetupCn = b(null);
const controlsCn = b('controls');
const requiredDndItemCn = b('required-item');

function identity<T>(value: T): T {
return value;
}

const b = block('table-column-setup');
const tableColumnSetupCn = b(null);
const controlsCn = b('controls');

const reorderArray = <T extends unknown>(list: T[], startIndex: number, endIndex: number): T[] => {
const result = [...list];
const [removed] = result.splice(startIndex, 1);
Expand All @@ -50,8 +49,7 @@ const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => {
...tableColumnItem,
startSlot: tableColumnItem.isRequired ? <Icon data={Lock} /> : undefined,
hasSelectionIcon,
// to overwrite select background effect - https://github.com/gravity-ui/uikit/blob/main/src/components/useList/components/ListItemView/ListItemView.tsx#L125
className: hasSelectionIcon ? undefined : requiredDndItemCn,
selected: hasSelectionIcon ? tableColumnItem.isSelected : undefined,
};
});
};
Expand Down Expand Up @@ -281,7 +279,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => {
return (
<TreeSelect
className={tableColumnSetupCn}
getItemContent={identity}
mapItemDataToProps={identity}
multiple
size="l"
open={open}
Expand Down
20 changes: 10 additions & 10 deletions src/components/TreeList/TreeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const TreeList = <T,>({
multiple,
setActiveItemId,
containerRef: propsContainerRef,
getItemContent,
mapItemDataToProps,
}: TreeListProps<T>) => {
const uniqId = useUniqId();
const treeListId = id ?? uniqId;
Expand All @@ -47,21 +47,23 @@ export const TreeList = <T,>({
onItemClick?.({
id: listItemId,
data: listParsedState.itemsById[listItemId],
isGroup: listItemId in listParsedState.groupsState,
disabled: disabledById
? Boolean(disabledById[listItemId])
: Boolean(listParsedState.initialState.disabledById[listItemId]),
isLastItem:
listParsedState.visibleFlattenIds[
listParsedState.visibleFlattenIds.length - 1
] === listItemId,
groupState: listParsedState.groupsState[listItemId],
itemState: listParsedState.itemsState[listItemId],
});
},
[
disabledById,
listParsedState.groupsState,
listParsedState.initialState.disabledById,
listParsedState.itemsById,
listParsedState.itemsState,
listParsedState.visibleFlattenIds,
onItemClick,
],
Expand All @@ -84,6 +86,7 @@ export const TreeList = <T,>({
const renderState = getItemRenderState({
id: itemId,
size,
mapItemDataToProps,
onItemClick: handleItemClick,
...listParsedState,
expandedById,
Expand All @@ -105,13 +108,7 @@ export const TreeList = <T,>({
});
}

return (
<ListItemView
{...renderState.props}
{...getItemContent(listParsedState.itemsById[itemId])}
{...renderContextProps}
/>
);
return <ListItemView {...renderState.props} {...renderContextProps} />;
};

// not JSX decl here is from weird `react-beautiful-dnd` render bug
Expand All @@ -121,7 +118,10 @@ export const TreeList = <T,>({
containerRef,
className: b(null, className),
...listParsedState,
...{expandedById, disabledById, activeItemId, selectedById},
expandedById,
disabledById,
activeItemId,
selectedById,
renderItem,
});
};
4 changes: 2 additions & 2 deletions src/components/TreeList/__stories__/stories/DefaultStory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function identity<T>(value: T): T {
}

export interface DefaultStoryProps
extends Omit<TreeListProps<{title: string}>, 'items' | 'getItemContent'> {
extends Omit<TreeListProps<{title: string}>, 'items' | 'mapItemDataToProps'> {
itemsCount?: number;
}

Expand All @@ -19,7 +19,7 @@ export const DefaultStory = ({itemsCount = 5, ...props}: DefaultStoryProps) => {

return (
<Flex width="500">
<TreeList {...props} items={items} getItemContent={identity} />
<TreeList {...props} items={items} mapItemDataToProps={identity} />
</Flex>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ function identity<T>(value: T): T {
export interface InfinityScrollStoryProps
extends Omit<
TreeListProps<{title: string}>,
'value' | 'onUpdate' | 'items' | 'multiple' | 'size' | 'getItemContent'
'value' | 'onUpdate' | 'items' | 'multiple' | 'size' | 'mapItemDataToProps'
> {
itemsCount?: number;
}

export const InfinityScrollStory = ({itemsCount = 5, ...storyProps}: InfinityScrollStoryProps) => {
const listState = useListState();

const handleItemClick: TreeListOnItemClick<{title: string}> = ({id, isGroup, disabled}) => {
const handleItemClick: TreeListOnItemClick<{title: string}> = ({id, groupState, disabled}) => {
if (disabled) return;

listState.setActiveItemId(id);

if (isGroup) {
if (groupState) {
listState.setExpanded((prevState) => ({
...prevState,
[id]: id in prevState ? !prevState[id] : false,
Expand All @@ -56,7 +56,7 @@ export const InfinityScrollStory = ({itemsCount = 5, ...storyProps}: InfinityScr
size="l"
{...storyProps}
{...listState}
getItemContent={identity}
mapItemDataToProps={identity}
items={items}
multiple
onItemClick={handleItemClick}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const randomItems: CustomDataType[] = createRandomizedData({
}).map(({data}, idx) => ({someRandomKey: data, id: String(idx)}));

export interface WithDndListStoryProps
extends Omit<TreeListProps<CustomDataType>, 'items' | 'getItemContent' | 'getItemContent'> {}
extends Omit<TreeListProps<CustomDataType>, 'items' | 'mapItemDataToProps'> {}

export const WithDndListStory = (storyProps: WithDndListStoryProps) => {
const [items, setItems] = React.useState(randomItems);
Expand Down Expand Up @@ -146,11 +146,11 @@ export const WithDndListStory = (storyProps: WithDndListStoryProps) => {
{...storyProps}
items={items}
{...listState}
getItemContent={({someRandomKey}) => ({title: someRandomKey})}
mapItemDataToProps={({someRandomKey}) => ({title: someRandomKey})}
// you can omit this prop here. If prop `id` passed, TreeSelect would take it by default
getId={({id}) => id}
onItemClick={({id, isGroup, disabled}) => {
if (!isGroup && !disabled) {
onItemClick={({id, groupState, disabled}) => {
if (!groupState && !disabled) {
listState.setSelected((prevState) => ({
[id]: !prevState[id],
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {RenderVirtualizedContainer} from '../components/RenderVirtualizedContain
export interface WithFiltrationAndControlsStoryProps
extends Omit<
TreeListProps<{title: string}>,
'value' | 'onUpdate' | 'items' | 'getItemContent'
'value' | 'onUpdate' | 'items' | 'mapItemDataToProps'
> {
itemsCount?: number;
}
Expand Down Expand Up @@ -58,10 +58,10 @@ export const WithFiltrationAndControlsStory = ({
<TreeList
{...treeSelectProps}
{...listState}
onItemClick={({id, isGroup, disabled}) => {
onItemClick={({id, groupState, disabled}) => {
if (disabled) return;

if (isGroup) {
if (groupState) {
listState.setExpanded((prevState) => ({
...prevState,
[id]: id in prevState ? !prevState[id] : false,
Expand All @@ -81,7 +81,7 @@ export const WithFiltrationAndControlsStory = ({

listState.setActiveItemId(id);
}}
getItemContent={(x) => x}
mapItemDataToProps={(x) => x}
renderContainer={renderContainer}
items={filterState.items}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface CustomDataStructure {
export interface WithGroupSelectionAndCustomIconStoryProps
extends Omit<
TreeListProps<CustomDataStructure>,
'value' | 'onUpdate' | 'items' | 'multiple' | 'cantainerRef' | 'size' | 'getItemContent'
'value' | 'onUpdate' | 'items' | 'multiple' | 'cantainerRef' | 'size' | 'mapItemDataToProps'
> {
itemsCount?: number;
}
Expand All @@ -43,7 +43,6 @@ export const WithGroupSelectionAndCustomIconStory = ({

const handleItemClick: TreeListOnItemClick<CustomDataStructure> = ({id, disabled}) => {
if (disabled) return;
console.log(1);

listState.setSelected((prevState) => ({
[id]: !prevState[id],
Expand All @@ -57,7 +56,7 @@ export const WithGroupSelectionAndCustomIconStory = ({
<TreeList
{...props}
size="l"
getItemContent={mapCustomDataStructureToKnownProps}
mapItemDataToProps={mapCustomDataStructureToKnownProps}
{...listState}
onItemClick={handleItemClick}
renderItem={({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function identity<T>(value: T): T {
export interface WithItemLinksAndActionsStoryProps
extends Omit<
TreeListProps<{title: string}>,
'items' | 'size' | 'multiple' | 'getItemContent'
'items' | 'size' | 'multiple' | 'mapItemDataToProps'
> {}

export const WithItemLinksAndActionsStory = (props: WithItemLinksAndActionsStoryProps) => {
Expand All @@ -30,11 +30,11 @@ export const WithItemLinksAndActionsStory = (props: WithItemLinksAndActionsStory
<TreeList
{...props}
{...listState}
getItemContent={identity}
mapItemDataToProps={identity}
size="l"
items={items}
onItemClick={({id, isGroup, disabled}) => {
if (!isGroup && !disabled) {
onItemClick={({id, groupState, disabled}) => {
if (!groupState && !disabled) {
listState.setSelected((prevState) => ({[id]: !prevState[id]}));
}
}}
Expand Down
16 changes: 10 additions & 6 deletions src/components/TreeList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import type {
ListParsedState,
ListState,
RenderItemContext,
RenderItemState,
RenderItemProps,
} from '../useList';

export type TreeListRenderItem<T, P extends {} = {}> = (props: {
data: T;
// required item props to render
props: RenderItemState;
props: RenderItemProps;
// internal list context props
itemState: RenderItemContext;
index: number;
Expand All @@ -24,13 +24,17 @@ export type TreeListRenderItem<T, P extends {} = {}> = (props: {

interface ItemClickContext<T> {
id: ListItemId;
isGroup: boolean;
/**
* Defined only if item is group
*/
groupState?: ListParsedState<T>['groupsState'][number];
itemState: ListParsedState<T>['itemsState'][number];
isLastItem: boolean;
disabled: boolean;
data: T;
}

export type TreeListOnItemClick<T> = (ctx: ItemClickContext<T>) => void;
export type TreeListOnItemClick<T, R = {}> = (ctx: ItemClickContext<T> & R) => void;

export type TreeListRenderContainerProps<T> = ListParsedState<T> &
Partial<ListState> & {
Expand All @@ -52,7 +56,7 @@ export type TreeListRenderContainer<T> = (
props: TreeListRenderContainerProps<T>,
) => React.JSX.Element;

export type TreeListRenderContent<T> = (item: T) => KnownItemStructure;
export type TreeListMapItemDataToProps<T> = (item: T) => KnownItemStructure;

export interface TreeListProps<T> extends QAProps, Partial<ListState> {
/**
Expand All @@ -77,7 +81,7 @@ export interface TreeListProps<T> extends QAProps, Partial<ListState> {
* If you want to disable default behavior pass `disabled` as a value;
*/
onItemClick?: TreeListOnItemClick<T>;
getItemContent: TreeListRenderContent<T>;
mapItemDataToProps: TreeListMapItemDataToProps<T>;
/**
* Required for keyboard correct work
*/
Expand Down
Loading

0 comments on commit dd736cc

Please sign in to comment.