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 vote down vote up
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 vote down vote up
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>
    );
  },
)