Skip to content

Commit

Permalink
chore: add useDndRenderContainer and useDndRenderItem
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanVor committed Feb 13, 2024
1 parent de3d679 commit 7c3aef7
Showing 1 changed file with 105 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,105 +69,30 @@ interface SwitcherProps {
onClick: React.MouseEventHandler<HTMLElement>;
}

type Item = TableColumnSetupItem &
TreeSelectItemProps & {
id: string;
isDragDisabled?: boolean;
};

export interface TableColumnSetupProps {
renderSwitcher?: (props: SwitcherProps) => React.JSX.Element;

items: TableColumnSetupItem[];
sortable?: boolean;

onUpdate: (newSettings: TableSetting[]) => void;
popupWidth?: TreeSelectProps<any>['popupWidth'];
popupPlacement?: PopperPlacement;
}

export const TableColumnSetup = (props: TableColumnSetupProps) => {
const {
renderSwitcher,
popupWidth,
popupPlacement,
items: propsItems,
onUpdate: propsOnUpdate,
sortable,
} = props;

const useDndRenderContainer = ({
onApply,
onDragEnd,
}: {
onDragEnd: OnDragEndResponder;
onApply: () => void;
}) => {
const uniqId = useUniqId();

const [open, setOpen] = React.useState(false);

const [items, setItems] = React.useState(propsItems);
const [prevPropsItems, setPrevPropsItems] = React.useState(propsItems);
if (propsItems !== prevPropsItems) {
setPrevPropsItems(propsItems);

const newItems = propsItems;
setItems(newItems);
}

const onApply = () => {
const newSettings = items.map<TableSetting>(({id, isSelected}) => ({id, isSelected}));
propsOnUpdate(newSettings);
setOpen(false);
};

const renderControl: TreeSelectProps<unknown>['renderControl'] = ({toggleOpen}) => {
const onKeyDown = createOnKeyDownHandler(toggleOpen);

return (
renderSwitcher?.({onClick: toggleOpen, onKeyDown}) || (
<Button onClick={toggleOpen} extraProps={{onKeyDown}}>
<Icon data={Gear} />
{i18n('button_switcher')}
</Button>
)
);
};

const onOpenChange = (open: boolean) => {
setOpen(open);

if (open === false) {
setItems(propsItems);
}
};

const onUpdate = (selectedItemsIds: string[]) => {
setItems((prevItems) => {
return prevItems.map((item) => ({
...item,
isSelected: selectedItemsIds.includes(item.id),
}));
});
};

const renderContainer: TreeSelectRenderContainer<Item> = ({
const dndRenderContainer: TreeSelectRenderContainer<Item> = ({
renderItem,
visibleFlattenIds,
items: _items,
containerRef,
id,
}) => {
const handleDrugEnd: OnDragEndResponder = ({destination, source}) => {
if (destination?.index !== undefined && destination?.index !== source.index) {
setItems((prevItems) => {
return reorderArray(prevItems, source.index, destination.index);
});
}
};

const visibleFlattenItemList = visibleFlattenIds.map((visibleFlattenId, idx) =>
renderItem(visibleFlattenId, idx),
);

return (
<React.Fragment>
<ListContainerView ref={containerRef} id={id}>
<DragDropContext onDragEnd={handleDrugEnd}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId={uniqId}>
{(droppableProvided) => {
return (
Expand All @@ -190,7 +115,11 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => {
);
};

const renderItem: TreeSelectRenderItem<Item> = ({data, props, index}) => {
return dndRenderContainer;
};

const useDndRenderItem = (sortable: boolean | undefined) => {
const renderDndItem: TreeSelectRenderItem<Item> = ({data, props, index}) => {
const isDragDisabled = sortable === false;

const endSlot =
Expand Down Expand Up @@ -235,6 +164,95 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => {
);
};

return renderDndItem;
};

type Item = TableColumnSetupItem &
TreeSelectItemProps & {
id: string;
isDragDisabled?: boolean;
};

export interface TableColumnSetupProps {
renderSwitcher?: (props: SwitcherProps) => React.JSX.Element;

items: TableColumnSetupItem[];
sortable?: boolean;

onUpdate: (newSettings: TableSetting[]) => void;
popupWidth?: TreeSelectProps<any>['popupWidth'];
popupPlacement?: PopperPlacement;
}

export const TableColumnSetup = (props: TableColumnSetupProps) => {
const {
renderSwitcher,
popupWidth,
popupPlacement,
items: propsItems,
onUpdate: propsOnUpdate,
sortable,
} = props;

const [open, setOpen] = React.useState(false);

const [items, setItems] = React.useState(propsItems);
const [prevPropsItems, setPrevPropsItems] = React.useState(propsItems);
if (propsItems !== prevPropsItems) {
setPrevPropsItems(propsItems);

const newItems = propsItems;
setItems(newItems);
}

const onApply = () => {
const newSettings = items.map<TableSetting>(({id, isSelected}) => ({id, isSelected}));
propsOnUpdate(newSettings);
setOpen(false);
};

const onDragEnd: OnDragEndResponder = ({destination, source}) => {
if (destination?.index !== undefined && destination?.index !== source.index) {
setItems((prevItems) => {
return reorderArray(prevItems, source.index, destination.index);
});
}
};

const dndRenderContainer = useDndRenderContainer({onApply, onDragEnd});

const dndRenderItem = useDndRenderItem(sortable);

const renderControl: TreeSelectProps<unknown>['renderControl'] = ({toggleOpen}) => {
const onKeyDown = createOnKeyDownHandler(toggleOpen);

return (
renderSwitcher?.({onClick: toggleOpen, onKeyDown}) || (
<Button onClick={toggleOpen} extraProps={{onKeyDown}}>
<Icon data={Gear} />
{i18n('button_switcher')}
</Button>
)
);
};

const onOpenChange = (open: boolean) => {
setOpen(open);

if (open === false) {
setItems(propsItems);
}
};

const onUpdate = (selectedItemsIds: string[]) => {
setItems((prevItems) => {
return prevItems.map((item) => ({
...item,
isSelected: selectedItemsIds.includes(item.id),
}));
});
};

const valueRef = React.useRef<string[]>();
if (valueRef.current === undefined || items !== prevPropsItems) {
valueRef.current = prepareValue(items);
Expand All @@ -257,9 +275,9 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => {
popupWidth={popupWidth}
onOpenChange={onOpenChange}
placement={popupPlacement}
renderContainer={renderContainer}
renderContainer={dndRenderContainer}
renderControl={renderControl}
renderItem={renderItem}
renderItem={dndRenderItem}
/>
);
};

0 comments on commit 7c3aef7

Please sign in to comment.