import React, { forwardRef, HTMLAttributes, useEffect, useState } from 'react'; import { FiltersMap } from '@wix/bex-core'; import { DragAndDropBulkSubmit, DragAndDropSubmit } from '../DragAndDrop'; import { NestedTableNestedModeState } from '../../state'; import { observer } from 'mobx-react-lite'; import { TableProps } from '@wix/design-system'; import { DragAndDropContext, IDragAndDropContext, } from '@wix/wix-style-react-incubator/drag-and-drop'; import { DragAndDropAnnouncements } from '../DragAndDrop/DragAndDropAnnouncements'; import { dragHandleTestEvents, sortableItemTestEvents, } from '../GridDragAndDropDndKit/dndTestEventHandlers'; import { addEventListener } from '@wix/bex-core/util'; import { NestedTableDragAndDropState } from './NestedTableDragAndDropState'; import { minimalRequiredWdsRuntimeCheck } from '../../minimalRequiredWdsRuntimeCheck'; import { validateNestedTableDragAndDropProps } from './validateNestedTableDragAndDropProps'; import { DragOverlayTestComponent } from '../DragAndDrop/DragOverlayTestComponent'; import { DragOverlayProps } from '@wix/wix-style-react-incubator/dnd-kit/core'; import { NestedTableDragAndDropOverlay } from './NestedTableDragAndDropOverlay'; import { createUseIsDropDisabled } from './createUseIsDropDisabled'; import { usePageContext } from '@wix/bex-core/react'; export interface NestedTableDragAndDropContextProps< C extends string, T, F extends FiltersMap, > { state: NestedTableNestedModeState; onSubmit?: DragAndDropSubmit; onBulkSubmit?: DragAndDropBulkSubmit; children: React.ReactElement< TableProps, React.ComponentType> >; } function _NestedTableDragAndDropContext< C extends string, T, F extends FiltersMap, >(props: NestedTableDragAndDropContextProps) { const { state: nestedState, onSubmit, onBulkSubmit, children } = props; const { type: Table, props: tableProps } = children; if (process.env.NODE_ENV !== 'production') { minimalRequiredWdsRuntimeCheck({ required: '^1.109.2', requiredBy: 'WixPatterns/NestedTable', }); validateNestedTableDragAndDropProps(nestedState); } const state = nestedState.nestedTableDragAndDrop as NestedTableDragAndDropState; const useIsDropDisabled = createUseIsDropDisabled(state); const dragAndDropState = state.dnd; const { modalsContainerRef } = usePageContext(); useEffect(() => state.init(), []); dragAndDropState.onSubmit = onSubmit; dragAndDropState.onBulkSubmit = onBulkSubmit; const [dragAndDropContext] = useState( (): IDragAndDropContext => ({ useIsDropDisabled, closestCenterOnViewPort: true, onDragAndDropDisabledRowPointerDown: (id, e) => { dragAndDropState.attachDisabledDragAttempt(id as string, e, 'y'); }, cancelDrop: async (ev) => { return dragAndDropState.beforeDrop(ev); }, dropAnimation: { duration: dragAndDropState.dropAnimation.duration, easing: dragAndDropState.dropAnimation.easing, }, announcements: dragAndDropState.nullAnnouncements, a11yContainer: modalsContainerRef.current, onDragOver: ({ over }) => dragAndDropState.onDragOver({ over }), onDragMove: (event) => dragAndDropState.onDragMove(event), restoreFocus: false, onDropAnimationEnd: (id, dragHandleRef) => { return addEventListener( dragAndDropState.events, 'dropAnimationEnd', () => { dragAndDropState.focusDragHandleIfDropped( id, dragHandleRef.current, ); }, ); }, overlayWrapperElement: forwardRef< HTMLDivElement, HTMLAttributes >((props, ref) => ( )), ...(process.env.NODE_ENV === 'test' && { DragOverlayComponentType: (props: DragOverlayProps) => ( ), }), keyboardCodes: dragAndDropState.keyboardCodes, autoScrollOptions: { acceleration: 6, }, hideOverlayBottomShadow: true, eventHandlers: { row: ({ id, disabled }) => { const testEvents = process.env.NODE_ENV === 'test' ? sortableItemTestEvents({ state: dragAndDropState, id, disabled, }) : undefined; return { ...testEvents, onPointerDown: (e) => { dragAndDropState.containerEvents.onPointerDown?.(e); testEvents?.onPointerDown?.(e); }, }; }, handle: ({ id }) => ({ onPointerDown: (e) => { dragAndDropState.handleEvents.onPointerDown?.(e); }, onKeyDown: (e) => { dragAndDropState.handleEvents.onKeyDown?.(e); }, ...(process.env.NODE_ENV === 'test' && dragHandleTestEvents({ state: dragAndDropState, id, })), }), }, }), ); dragAndDropContext.a11yContainer = modalsContainerRef.current; return ( dragAndDropState.onDragStart(event)} onDragEnd={(event) => dragAndDropState.onDragEnd(event)} onDragCancel={() => dragAndDropState.onDragCancel()} /> ); } export const NestedTableDragAndDropContext = observer( _NestedTableDragAndDropContext, );