Skip to content

Commit

Permalink
feat: add onDropDragOver callback for dnd wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
flops committed Oct 28, 2024
1 parent a23ad55 commit caaa762
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 34 deletions.
38 changes: 33 additions & 5 deletions src/components/DashKit/__stories__/DashKitGroupsShowcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const GRID_COLUMNS = 36;

export const DashKitGroupsShowcase: React.FC = () => {
const [editMode, setEditMode] = React.useState(true);
const [headerInteractions, setHeaderInteractions] = React.useState(true);

const onClick = () => {
console.log('click');

Check warning on line 35 in src/components/DashKit/__stories__/DashKitGroupsShowcase.tsx

View workflow job for this annotation

GitHub Actions / Verify Files

Unexpected console statement
Expand Down Expand Up @@ -112,29 +113,38 @@ export const DashKitGroupsShowcase: React.FC = () => {
);
},
gridProperties: (props: ReactGridLayoutProps) => {
return {
const overrideProps: ReactGridLayoutProps = {
...props,
compactType: 'horizontal-nowrap',
maxRows: MAX_ROWS,
};

if (headerInteractions) {
return overrideProps;
}

return {
...overrideProps,
noOverlay: true,
isResizable: false,
isDraggable: false,
resizeHandles: [],
};
},
},
{
id: DEFAULT_GROUP,
gridProperties: (props: ReactGridLayoutProps) => {
const copy = {...props};

return {
...copy,
...props,
compactType: null,
allowOverlap: true,
resizeHandles: ['s', 'w', 'e', 'n', 'sw', 'nw', 'se', 'ne'],
};
},
},
],
[],
[headerInteractions],
);

const overlayMenuItems = React.useMemo(() => {
Expand Down Expand Up @@ -280,12 +290,29 @@ export const DashKitGroupsShowcase: React.FC = () => {
onDragEnd={() => {
console.log('dragEnded');
}}
onDropDragOver={(item) => {
if (!headerInteractions && item.parent === fixedGroup) {
return false;
}

return true;
}}
>
<Demo title="Groups">
<DemoRow title="Controls">
<Button view="action" size="m" onClick={() => setEditMode(!editMode)}>
{editMode ? 'Disable editMode' : 'Enable editMode'}
</Button>
<Button
view="action"
size="m"
onClick={() => setHeaderInteractions(!headerInteractions)}
disabled={!editMode}
>
{headerInteractions
? 'Disable header interactions'
: 'Enable header interactions'}
</Button>
</DemoRow>
<DemoRow title="Component view">
<DashKit
Expand All @@ -297,6 +324,7 @@ export const DashKitGroupsShowcase: React.FC = () => {
overlayMenuItems={overlayMenuItems}
onDragStart={updateConfigOrder}
onResizeStart={updateConfigOrder}
context={{editModeHeader: headerInteractions}}
/>
<ActionPanel items={items} />
</DemoRow>
Expand Down
2 changes: 1 addition & 1 deletion src/components/DashKit/__stories__/Demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
overflow: auto;
top: 0;
z-index: 3;
min-height: 44px;
min-height: 52px;
display: flex;
flex-direction: column;
margin-bottom: 8px;
Expand Down
19 changes: 13 additions & 6 deletions src/components/DashKitDnDWrapper/DashKitDnDWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';

import {DashKitDnDContext} from '../../context/DashKitContext';
import type {ItemDragProps} from '../../shared';
import type {ItemDragProps, ItemDropDragOver} from '../../shared';

type DashKitDnDWrapperProps = {
dragImageSrc?: string;
onDropDragOver?: (
draggedItem: ItemDropDragOver,
sharedItem: ItemDropDragOver | null,
) => void | boolean;
onDragStart?: (dragProps: ItemDragProps) => void;
onDragEnd?: () => void;
children: React.ReactElement;
Expand All @@ -22,20 +26,22 @@ export const DashKitDnDWrapper: React.FC<DashKitDnDWrapperProps> = (props) => {
return img;
}, [props.dragImageSrc]);

const onDragStartProp = props.onDragStart;
const onDragStart = React.useCallback(
(_: React.DragEvent<Element>, itemDragProps: ItemDragProps) => {
setDragProps(itemDragProps);
props.onDragStart?.(itemDragProps);
onDragStartProp?.(itemDragProps);
},
[setDragProps, props.onDragStart],
[setDragProps, onDragStartProp],
);

const onDragEndProp = props.onDragEnd;
const onDragEnd = React.useCallback(
(_: React.DragEvent<Element>) => {
setDragProps(null);
props.onDragEnd?.();
onDragEndProp?.();
},
[setDragProps, props.onDragEnd],
[setDragProps, onDragEndProp],
);

const contextValue = React.useMemo(() => {
Expand All @@ -44,8 +50,9 @@ export const DashKitDnDWrapper: React.FC<DashKitDnDWrapperProps> = (props) => {
dragImagePreview,
onDragStart,
onDragEnd,
onDropDragOver: props.onDropDragOver,
};
}, [dragProps, dragImagePreview, onDragStart, onDragEnd]);
}, [dragProps, dragImagePreview, onDragStart, onDragEnd, props.onDropDragOver]);

return (
<DashKitDnDContext.Provider value={contextValue}>
Expand Down
27 changes: 17 additions & 10 deletions src/components/GridLayout/GridLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,17 @@ export default class GridLayout extends React.PureComponent {
const {h, w, i} = currentDraggingElement.layoutItem;
const {type} = currentDraggingElement.item;

return onDropDragOver(e, properties, layout, {h, w, i, type});
return onDropDragOver(e, group, properties, layout, {
h,
w,
i,
type,
parent: currentDraggingElement.group,
});
}

if (dragOverPlugin) {
return onDropDragOver(e, properties, layout);
return onDropDragOver(e, group, properties, layout);
}

return false;
Expand Down Expand Up @@ -581,11 +587,9 @@ export default class GridLayout extends React.PureComponent {
} = this.context;

const {currentDraggingElement, draggedOverGroup} = this.state;

const properties = groupGridProperties
? groupGridProperties({
...registerManager.gridLayout,
})
const hasOwnGroupProperties = typeof groupGridProperties === 'function';
const properties = hasOwnGroupProperties
? groupGridProperties({...registerManager.gridLayout})
: registerManager.gridLayout;
let {compactType} = properties;

Expand Down Expand Up @@ -637,7 +641,9 @@ export default class GridLayout extends React.PureComponent {
const isDraggedOut = isCurrentItem && this.state.draggedOut;
const isDragging = this.state.isDragging;
const itemNoOverlay =
'noOverlay' in properties ? properties.noOverlay : noOverlay;
hasOwnGroupProperties && 'noOverlay' in properties
? properties.noOverlay
: noOverlay;

return (
<GridItem
Expand Down Expand Up @@ -720,13 +726,14 @@ export default class GridLayout extends React.PureComponent {
offset += items.length;

if (group.render) {
return group.render(id, element, {
const groupContext = {
config,
editMode,
items,
layout,
context,
});
};
return group.render(id, element, groupContext);
}

return element;
Expand Down
48 changes: 36 additions & 12 deletions src/hocs/withContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,15 @@ function useMemoStateContext(props) {
pluginsRefs.forEach((ref) => ref && ref.reload && ref.reload(data));
}, []);

const dragProps = dndContext?.dragProps;
const dragPropsContext = dndContext?.dragProps;
const onDropDragOverContext = dndContext?.onDropDragOver;

const dragOverPlugin = React.useMemo(() => {
if (!dragProps) {
if (!dragPropsContext) {
return null;
}

const pluginType = dragProps.type;
const pluginType = dragPropsContext.type;

if (props.registerManager.check(pluginType)) {
return props.registerManager.getItem(pluginType);
Expand All @@ -333,10 +334,10 @@ function useMemoStateContext(props) {
console.error(`Uknown pluginType: ${pluginType}`);
return null;
}
}, [dragProps, props.registerManager]);
}, [dragPropsContext, props.registerManager]);

const onDropDragOver = React.useCallback(
(_e, gridProps, groupLayout, sharedItem) => {
(_e, group, gridProps, groupLayout, sharedItem) => {
if (temporaryLayout) {
resetTemporaryLayout();
return false;
Expand Down Expand Up @@ -372,26 +373,49 @@ function useMemoStateContext(props) {
const {
h = defaultLayout?.h || DEFAULT_WIDGET_HEIGHT,
w = defaultLayout?.w || DEFAULT_WIDGET_WIDTH,
} = dragProps?.layout || {};
} = dragPropsContext?.layout || {};

return {
const resultLayout = {
h: maxH ? Math.min(h, maxH) : h,
w: maxW ? Math.min(w, maxW) : w,
};

if (
onDropDragOverContext &&
onDropDragOverContext?.(
{
...sharedItem,
...resultLayout,
...dragPropsContext,
parent: group,
},
sharedItem ?? null,
) === false
) {
return false;
}

return resultLayout;
},
[resetTemporaryLayout, temporaryLayout, dragOverPlugin, dragProps],
[
resetTemporaryLayout,
temporaryLayout,
dragOverPlugin,
dragPropsContext,
onDropDragOverContext,
],
);

const onDropProp = props.onDrop;
const onDrop = React.useCallback(
(newLayout, item) => {
if (!dragProps) {
if (!dragPropsContext) {
return;
}

setTemporaryLayout({
data: [...newLayout, item],
dragProps,
dragProps: dragPropsContext,
});

onDropProp({
Expand All @@ -404,10 +428,10 @@ function useMemoStateContext(props) {
}, []),
itemLayout: pick(item, ITEM_PROPS),
commit: resetTemporaryLayout,
dragProps,
dragProps: dragPropsContext,
});
},
[dragProps, onDropProp, setTemporaryLayout, resetTemporaryLayout],
[dragPropsContext, onDropProp, setTemporaryLayout, resetTemporaryLayout],
);

const dashkitContextValue = React.useMemo(
Expand Down
5 changes: 5 additions & 0 deletions src/shared/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export type ItemDragProps = {
extra?: any;
};

export type ItemDropDragOver = Omit<ConfigLayout, 'x' | 'y' | 'i'> & {
type: string;
i?: ConfigLayout['i'];
};

export type ItemDropProps = {
commit: () => void;
dragProps: ItemDragProps;
Expand Down

0 comments on commit caaa762

Please sign in to comment.