react-beautiful-dnd#BeforeCapture TypeScript Examples
The following examples show how to use
react-beautiful-dnd#BeforeCapture.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useDnd.ts From TabMerger with GNU General Public License v3.0 | 5 votes |
export default function useDnd() {
const dispatch = useDispatch();
const [groupTitle] = useLocalStorage("groupTitle", DEFAULT_GROUP_TITLE);
const [groupColor] = useLocalStorage("groupColor", DEFAULT_GROUP_COLOR);
const [windowTitle] = useLocalStorage("windowTitle", DEFAULT_WINDOW_TITLE);
const { active } = useSelector((state) => state.groups.present);
const { index } = active;
const onBeforeCapture = useCallback(
({ draggableId }: BeforeCapture) => {
const windowDrag = isWindowDrag(draggableId);
const tabDrag = isTabDrag(draggableId);
if (windowDrag) {
// Hide tabs during a window drag
toggleWindowTabsVisibility(draggableId, false);
} else if (tabDrag) {
// Add window to end of group (only if not in the first group)
index > 0 && dispatch(addWindow({ index, name: windowTitle }));
}
if (windowDrag || tabDrag) {
// Add group to end of side panel on both tab and window drag types
dispatch(addGroup({ title: groupTitle, color: groupColor }));
}
},
[dispatch, index, groupTitle, groupColor, windowTitle]
);
const onDragStart = useCallback(
({ draggableId }: DragStart) => {
dispatch(updateDragOriginType(draggableId));
dispatch(updateIsDragging(true));
},
[dispatch]
);
const onDragEnd = useCallback(
({ source, destination, combine, draggableId }: DropResult) => {
const [isTab, isWindow, isGroup] = [isTabDrag, isWindowDrag, isGroupDrag].map((cb) => cb(draggableId));
const commonPayload = { index, source };
const sidePanelPayload = { ...commonPayload, combine };
const destPayload = { ...commonPayload, destination };
const isValidCombine = combine && Number(combine.draggableId.split("-")[1]) > 0;
const isValidDndWithinGroup = destination && destination.droppableId !== "sidePanel";
if (isTab) {
isValidCombine && dispatch(updateTabsFromSidePanelDnd({ ...sidePanelPayload, name: windowTitle }));
isValidDndWithinGroup && dispatch(updateTabsFromGroupDnd(destPayload));
} else if (isWindow) {
// Re-show the tabs since the drag ended
toggleWindowTabsVisibility(draggableId, true);
isValidCombine && dispatch(updateWindowsFromSidePanelDnd(sidePanelPayload));
isValidDndWithinGroup && dispatch(updateWindowsFromGroupDnd(destPayload));
} else if (isGroup && destination && destination.index > 0) {
// Only swap if the destination exists (valid) and is below the first group
dispatch(updateGroupOrder({ source, destination }));
}
dispatch(resetDnDInfo());
/**
* Must clear the windows in the current group first, then clear the group
* @note Only relevant for tab or window dragging since a group drag does not add either a (temporary) window or group
*/
if (isTab || isWindow) {
dispatch(clearEmptyWindows({ index }));
dispatch(clearEmptyGroups(active));
}
},
[dispatch, index, windowTitle, active]
);
return { onBeforeCapture, onDragStart, onDragEnd };
}
Example #2
Source File: index.tsx From S2 with MIT License | 4 votes |
SwitcherContent: React.FC<SwitcherContentProps> = React.memo(
(props) => {
const {
innerContentClassName,
contentTitleText = i18n('行列切换'),
resetText = i18n('恢复默认'),
onToggleVisible,
onSubmit,
sheetType,
...defaultFields
} = props;
const defaultState = getSwitcherState(defaultFields);
const [state, setState] = React.useState<SwitcherState>(defaultState);
const [draggingItemId, setDraggingItemId] = React.useState<string>(null);
const SWITCHER_CONFIG = React.useMemo(getSwitcherConfig, []);
const onBeforeDragStart = (initial: BeforeCapture) => {
setDraggingItemId(initial.draggableId);
};
const onDragEnd = ({ destination, source }: DropResult) => {
// reset dragging item id
setDraggingItemId(null);
// cancelled or drop to where can't drop
if (!destination) {
return;
}
// don't change position
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
const updatedState = moveItem(
state[source.droppableId],
state[destination.droppableId],
source,
destination,
);
setState({ ...state, ...updatedState });
};
const onReset = () => {
setState(defaultState);
};
const onConfirm = () => {
onToggleVisible();
onSubmit?.(generateSwitchResult(state));
};
const onVisibleItemChange = (
fieldType: FieldType,
checked: boolean,
id: string,
parentId?: string,
) => {
const updatedState = checkItem(state[fieldType], checked, id, parentId);
setState({
...state,
[fieldType]: updatedState,
});
};
const isNothingChanged = isEqual(defaultState, state);
const displayFieldItems = SWITCHER_FIELDS.filter(
(filed) => sheetType !== 'table' || filed === FieldType.Cols,
);
return (
<DragDropContext
onBeforeCapture={onBeforeDragStart}
onDragEnd={onDragEnd}
>
<div
className={cx(
innerContentClassName,
getSwitcherClassName(CLASS_NAME_PREFIX),
)}
>
<header className={getSwitcherClassName(CLASS_NAME_PREFIX, 'header')}>
{contentTitleText}
</header>
<main
className={cx(
getSwitcherClassName(CLASS_NAME_PREFIX, 'main'),
getMainLayoutClassName(sheetType),
)}
>
{displayFieldItems.map((type) => (
<Dimension
{...defaultFields[type]}
key={type}
fieldType={type}
items={state[type]}
crossRows={shouldCrossRows(sheetType, type)}
droppableType={SWITCHER_CONFIG[type].droppableType}
draggingItemId={draggingItemId}
onVisibleItemChange={onVisibleItemChange}
/>
))}
</main>
<footer className={getSwitcherClassName(CLASS_NAME_PREFIX, 'footer')}>
<Button
type={'text'}
icon={<ReloadOutlined />}
className={getSwitcherClassName(
CLASS_NAME_PREFIX,
'footer',
'reset-button',
)}
disabled={isNothingChanged}
onClick={onReset}
>
{resetText}
</Button>
<div
className={getSwitcherClassName(
CLASS_NAME_PREFIX,
'footer',
'actions',
)}
>
<Button className="action-button" onClick={onToggleVisible}>
{i18n('取消')}
</Button>
<Button
className="action-button"
type="primary"
disabled={isNothingChanged}
onClick={onConfirm}
>
{i18n('确定')}
</Button>
</div>
</footer>
</div>
</DragDropContext>
);
},
)