Chore: Improve dropdown draggable list (#1738)

* draggable menu item component

* Menu item isDragged prop removed

* Droppable list component

* Draggablee item component

* Drag and drop use refactor

* lint fix

* isDragDisabled check on DraggableItem

* revert changes on non visibility items

* MenuItemDraggable stroybook

* DraggableItem storybook

* lint fix

* lint fix

* BoardColumnMenu css fix

* showGrip prop addition

* isDragged css fix
This commit is contained in:
Aditya Pimpalkar
2023-10-04 14:56:25 +01:00
committed by GitHub
parent 1e402aca5f
commit 93a01c7292
11 changed files with 368 additions and 91 deletions
@@ -0,0 +1,53 @@
import { Meta, StoryObj } from '@storybook/react';
import { IconBell } from '@/ui/icon';
import { MenuItemDraggable } from '@/ui/menu-item/components/MenuItemDraggable';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { DraggableItem } from '../components/DraggableItem';
import { DroppableList } from '../components/DroppableList';
const meta: Meta<typeof DraggableItem> = {
title: 'ui/draggable-list/DraggableItem',
component: DraggableItem,
decorators: [
(Story, { parameters }) => (
<DroppableList
droppableId={parameters.droppableId}
onDragEnd={parameters.onDragEnd}
draggableItems={<Story />}
/>
),
ComponentDecorator,
],
parameters: {
droppableId: 'droppable',
onDragEnd: () => console.log('dragged'),
},
args: {
draggableId: 'draggable-1',
key: 'key-1',
index: 0,
isDragDisabled: false,
itemComponent: (
<>
<MenuItemDraggable
LeftIcon={IconBell}
key="key-1"
text="Draggable item 1"
/>
<MenuItemDraggable
LeftIcon={IconBell}
key="key-2"
text="Draggable item 2"
/>
</>
),
},
};
export default meta;
type Story = StoryObj<typeof DraggableItem>;
export const Default: Story = {};
@@ -0,0 +1,57 @@
import React from 'react';
import { useTheme } from '@emotion/react';
import { Draggable } from '@hello-pangea/dnd';
type DraggableItemProps = {
key: string;
draggableId: string;
isDragDisabled?: boolean;
index: number;
itemComponent: JSX.Element;
};
export const DraggableItem = ({
key,
draggableId,
isDragDisabled = false,
index,
itemComponent,
}: DraggableItemProps) => {
const theme = useTheme();
return (
<Draggable
key={key}
draggableId={draggableId}
index={index}
isDragDisabled={isDragDisabled}
>
{(draggableProvided, draggableSnapshot) => {
const draggableStyle = draggableProvided.draggableProps.style;
const isDragged = draggableSnapshot.isDragging;
return (
<div
ref={draggableProvided.innerRef}
{...{
...draggableProvided.draggableProps,
style: {
...draggableStyle,
left: 'auto',
top: 'auto',
transform: draggableStyle?.transform?.replace(
/\(-?\d+px,/,
'(0,',
),
background: isDragged
? theme.background.transparent.light
: 'none',
},
}}
{...draggableProvided.dragHandleProps}
>
{itemComponent}
</div>
);
}}
</Draggable>
);
};
@@ -0,0 +1,37 @@
import styled from '@emotion/styled';
import {
DragDropContext,
Droppable,
OnDragEndResponder,
} from '@hello-pangea/dnd';
type DroppableListProps = {
droppableId: string;
draggableItems: React.ReactNode;
onDragEnd: OnDragEndResponder;
};
const StyledDragDropItemsWrapper = styled.div`
width: 100%;
`;
export const DroppableList = ({
droppableId,
draggableItems,
onDragEnd,
}: DroppableListProps) => {
return (
<DragDropContext onDragEnd={onDragEnd}>
<StyledDragDropItemsWrapper>
<Droppable droppableId={droppableId}>
{(provided) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
{draggableItems}
{provided.placeholder}
</div>
)}
</Droppable>
</StyledDragDropItemsWrapper>
</DragDropContext>
);
};