import { useState, useEffect, useRef } from '@wordpress/element'; import { useControlSettingSet } from '../_hooks'; import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, type DragEndEvent, } from '@dnd-kit/core'; import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, } from '@dnd-kit/sortable'; // 要素内のみで制限するようにする import { restrictToParentElement } from "@dnd-kit/modifiers"; import SortableItem from './SortableItem'; import { __ } from '@wordpress/i18n'; type Props = { values: SortItems, title: string, description?: string, onChange: (newValues: string[]) => void, disabledSort?: string[], } export default function ApuraSortable({values, title, description, onChange, disabledSort}: Props) { const [sortItems, setSortItems] = useState(values); const [isInitialized, setIsInitialized] = useState(false); const initTimeoutRef = useRef | null>(null); // センサーの初期化を遅延実行 const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8, // 8px移動してからドラッグ開始 }, }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }) ); // コンポーネントマウント後の遅延初期化 useEffect(() => { // iframe環境での初期化を少し遅延させる initTimeoutRef.current = setTimeout(() => { setIsInitialized(true); }, 100); return () => { if (initTimeoutRef.current) { clearTimeout(initTimeoutRef.current); } }; }, []); // valuesが変更された時の処理 useEffect(() => { setSortItems(values); }, [values]); function handleDragEnd(event: DragEndEvent) { const {active, over} = event; if (active.id !== over?.id) { setSortItems((items) => { const oldIndex = items.findIndex( (item) => item.id === active.id ); const newIndex = items.findIndex( (item) => item.id === over.id ); return arrayMove(items, oldIndex, newIndex); }); } } function handleItemActive(id:string) { const newValues = sortItems.map((_item, i) =>{ if (_item.id === id) { // Return a new number return { ..._item, isActive: !_item.isActive, }; } else { // No change return _item; } }); // Re-render with the new array setSortItems(newValues); } // Update. useEffect(() => { const result = sortItems.flatMap(obj => obj.isActive ? obj.id : []); onChange(result); }, [sortItems, onChange]); return (
{title}
{description &&
{description}
} {isInitialized ? ( {sortItems.map(item => { return ( handleItemActive(item.id)} /> ) })} ) : ( // 初期化中の表示(DndContextなし)
{sortItems.map(item => ( handleItemActive(item.id)} /> ))}
)}
); }