Skip to content

FreeformItem

Individual draggable item component. Automatically registers with the parent TheFreeform.

Basic Usage

vue
<FreeformItem :item="item" />

Props

PropTypeDefaultDescription
itemFreeformItemDatarequiredItem data (must have id)
disabledbooleanfalseDisable dragging for this item
asDropZonebooleanfalseForce this item to be a drop target
accept(items) => boolean-Validate if drop is allowed

Slot Props

The default slot receives state information:

vue
<FreeformItem :item="item">
  <template #default="{ item, selected, dragging, dropTarget, dropAccepted }">
    <div :class="{
      'ring-blue-500': selected,
      'opacity-50': dragging,
      'ring-green-500': dropTarget && dropAccepted,
      'ring-red-500': dropTarget && !dropAccepted,
    }">
      {{ item.name }}
    </div>
  </template>
</FreeformItem>
PropTypeDescription
itemobjectThe item data
selectedbooleanItem is selected
draggingbooleanItem is being dragged
dropTargetbooleanItem is a drop target (hovering)
dropAcceptedbooleanDrop would be accepted

Containers

Items with type: 'container' automatically become drop targets:

ts
const items = ref([
  { id: 'folder', type: 'container' },  // Drop target
  { id: 'file' },                        // Normal item
])

Or force any item to be a drop target:

vue
<FreeformItem :item="item" :as-drop-zone="true" />

Accept Function

Control which drops are allowed:

vue
<FreeformItem
  :item="folder"
  :accept="acceptFiles"
>
ts
// Only accept non-folder items
function acceptFiles(draggedItems: FreeformItemData[]) {
  return draggedItems.every(item => item.type !== 'container')
}

When the accept function returns false:

  • Visual feedback shows red instead of green
  • The @drop-into event still fires with accepted: false

Default Styling

Without a custom slot, items get default styling:

  • Normal: Neutral background
  • Selected: Primary ring
  • Dragging: Reduced opacity
  • Container (drop target): Green or red ring based on accepted

Override by providing a custom slot template.

MIT Licensed