import { Collapse, Flex, Stack, Text, createStyles } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; import { IconChevronDown, IconGripVertical } from '@tabler/icons-react'; import { Reorder, useDragControls } from 'framer-motion'; import { FC, useEffect, useRef } from 'react'; import { IDraggableEditableListInputValue } from '../../../../../widgets/widgets'; interface DraggableListProps { items: { data: { id: string } & any; }[]; value: IDraggableEditableListInputValue['defaultValue']; onChange: (value: IDraggableEditableListInputValue['defaultValue']) => void; options: IDraggableEditableListInputValue; } export const DraggableList = ({ items, value, onChange, options }: DraggableListProps) => (
x.data.id)} onReorder={(order) => onChange(order.map((id) => value.find((v) => v.id === id)!))} as="div" > {items.map(({ data }) => ( { onChange( items.map((item) => { if (item.data.id === data.id) return data; return item.data; }) ); }} delete={() => { onChange(items.filter((item) => item.data.id !== data.id).map((item) => item.data)); }} /> ))}
); const ListItem: FC<{ item: any; label: string | JSX.Element; }> = ({ item, label, children }) => { const [opened, handlers] = useDisclosure(false); const { classes, cx } = useStyles(); const controls = useDragControls(); // Workaround for mobile drag controls not working // https://github.com/framer/motion/issues/1597#issuecomment-1235026724 const dragRef = useRef(null); useEffect(() => { const touchHandler: EventListener = (e) => e.preventDefault(); const dragItem = dragRef.current; if (dragItem) { dragItem.addEventListener('touchstart', touchHandler, { passive: false }); return () => { dragItem.removeEventListener('touchstart', touchHandler); }; } return undefined; }, [dragRef]); return (
controls.start(e)}>
{label}
handlers.toggle()} size={18} stroke={1.5} />
{children}
); }; const useStyles = createStyles((theme) => ({ container: { display: 'flex', flexDirection: 'column', borderRadius: theme.radius.md, border: `1px solid ${ theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[2] }`, backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.white, marginBottom: theme.spacing.xs, }, row: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 16px', gap: theme.spacing.sm, }, middle: { flexGrow: 1, }, symbol: { fontSize: 16, }, clickableIcons: { color: theme.colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.gray[6], cursor: 'pointer', userSelect: 'none', transition: 'transform .3s ease-in-out', }, rotate: { transform: 'rotate(180deg)', }, collapseContent: { padding: '12px 16px', }, }));