Skip to content

Instantly share code, notes, and snippets.

@ZanzyTHEbar
Created August 16, 2023 23:31
Show Gist options
  • Save ZanzyTHEbar/a6b104bf6e16453e6c94a25ee54dd9e4 to your computer and use it in GitHub Desktop.
Save ZanzyTHEbar/a6b104bf6e16453e6c94a25ee54dd9e4 to your computer and use it in GitHub Desktop.
solid-dnd
import {
useDragDropContext,
DragDropProvider,
DragDropSensors,
DragOverlay,
SortableProvider,
createSortable,
closestCenter,
} from '@thisbeyond/solid-dnd'
import { For, JSXElement, createSignal } from 'solid-js'
import { debug } from 'tauri-plugin-log-api'
import TriggerComponent from './Trigger'
import { ENotificationType } from '@src/static/types/enums'
import { useAppContext } from '@store/context/app'
import { useAppNotificationsContext } from '@store/context/notifications'
import { TriggerGroup } from '@static/types/interfaces'
export interface IProps {
header: string
}
interface ISortable extends TriggerGroup {
onRemove: (id: string | number) => void
}
const Sortable = (props: ISortable) => {
const sortable = createSortable(props.id)
const [state] = useDragDropContext()
return (
<div
use:sortable
class="sortable"
classList={{
'opacity-25': sortable.isActiveDraggable,
'transition-transform': !!state.active.draggable,
}}>
<TriggerComponent
title={props.title}
key={props.key}
start={props.start}
end={props.end}
id={props.id}
position={props.position}
onClick={props.onRemove}
/>
</div>
)
}
const TriggerGroups = (props: IProps) => {
const {
getSelectedVideoProjectTriggerGroups,
getSelectedVideoProject,
removeProjectTriggerGroup,
} = useAppContext()
const { addNotification } = useAppNotificationsContext()
debug(`[Trigger Groups]: ${JSON.stringify(getSelectedVideoProjectTriggerGroups())}`)
const onRemove = (id: string | number) => {
debug(`[Trigger Group]: Removing ${id}`)
addNotification({
title: 'Removed Trigger Group',
message: `Removed Animation Trigger Group ${id}`,
type: ENotificationType.WARNING,
})
removeProjectTriggerGroup(getSelectedVideoProject(), id)
}
const [items, setItems] = createSignal(getSelectedVideoProjectTriggerGroups())
const [activeItem, setActiveItem] = createSignal(null)
const ids = () => items()
const onDragStart = ({ draggable }) => setActiveItem(draggable.id)
const onDragEnd = ({ draggable, droppable }) => {
if (draggable && droppable) {
const currentItems = ids()
const fromIndex = currentItems.indexOf(draggable.id)
const toIndex = currentItems.indexOf(droppable.id)
if (fromIndex !== toIndex) {
const updatedItems = currentItems.slice()
updatedItems.splice(toIndex, 0, ...updatedItems.splice(fromIndex, 1))
setItems(updatedItems)
}
}
}
return (
<div class="flex flex-col justify-center grow bg-[#333742] rounded-xl pl-4 pr-4 pb-4 pt-4 h-[876px]">
<div class="flex grow rounded-xl flex-col pl-3 pr-3 pb-3 pt-3 bg-[#333742] text-white">
<div class="flex justify-between pb-3">
<div>
<p class="font-[700] text-lg">{props.header}</p>
</div>
</div>
</div>
<div class="video_grid draggable_container overflow-auto">
<DragDropProvider
onDragStart={onDragStart}
onDragEnd={onDragEnd}
collisionDetector={closestCenter}>
<DragDropSensors />
<div class="column self-stretch">
<SortableProvider ids={ids().map((e) => e.id)}>
<For each={items()}>
{(group) => (
<Sortable
title={group.title}
key={group.key}
start={group.start}
end={group.end}
id={group.id}
position={group.position}
onRemove={onRemove}
/>
)}
</For>
</SortableProvider>
</div>
<DragOverlay>
<div class="sortable">{activeItem()}</div>
</DragOverlay>
</DragDropProvider>
</div>
</div>
)
}
export default TriggerGroups
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment