# Development & Custom Extensions

> Learn how Custom Interfaces integrate with Collaborative Editing in Directus.

**Collaborative Editing works out-of-the-box for most Custom Interfaces**.

Unlike the previous extension-based implementation, you do **not** need to add specific data attributes to your components. The system automatically handles presence, field locking, and synchronization through the `v-form` and `form-field` wrappers.

## How it Works

When your Custom Interface is rendered within a Directus Form:

1. **Automatic wrapping**: Your interface is wrapped by the `form-field` component.
2. **Event Detection**: The wrapper listens for standard DOM `focusin` and `focusout` events bubbling up from your component.
3. **State Management**: When your component receives focus, the wrapper automatically notifies the collaboration system to "lock" the field for other users and display your avatar.

## Requirements for Custom Interfaces

For your custom interface to fully support collaborative editing, ensure the following:

### 1. Event Bubbling

Your component should allow `focus` and `blur` (or `focusin`/`focusout`) events to bubble up to the parent. This is standard behavior for native HTML inputs (`<input>`, `<textarea>`, etc.).

### 2. Standard Value Emission

Ensure your component emits the `update:modelValue` event when data changes, as per standard Vue 3 component design. This ensures real-time updates are propagated to other connected users.

```javascript
emit('update:modelValue', newValue);
```

### 3. Read-Only State

Respect the `disabled` prop. When a field is locked by another user, Directus passes `disabled: true` to your interface. Ensure your component visually reflects this state and prevents user interaction.

```typescript
defineProps({
    disabled: {
        type: Boolean,
        default: false,
    },
    // ...
});
```

## Troubleshooting

If your interface is not triggering the "locked" state for other users:

- **Check Event Bubbling**: If you use `event.stopPropagation()` on focus events, the wrapper will not detect the user's presence.
- **Focusable Elements**: Ensure the element that users interact with is actually focusable (e.g., has a `tabindex` if it's not a native input).

## Helper Utilities

Directus provides built-in utilities to help manage focus states in complex interfaces.

### `v-prevent-focusout` Directive

Use this directive to prevent the `focusout` event from bubbling when interacting with specific elements (like dropdowns, modals, or drawers) that are part of your interface but might technically sit outside the DOM hierarchy or trigger a blur.

```vue
<!-- Prevents losing the "locked" state when clicking inside this drawer -->
<v-drawer v-prevent-focusout="isOpen" ...>
  ...
</v-drawer>
```

### `useFocusin` Composable

If your component doesn't have a native input to trigger focus (e.g., a purely visual selector), you can use `useFocusin` to manually dispatch focus events.

```javascript
import { useFocusin } from '@/composables/use-focusin';

const { active, focus, blur } = useFocusin(containerRef);

// Manually trigger 
focus();
```

## Advanced Implementation

If you are building complex interfaces that do not rely on standard focus events (e.g., a canvas-based editor), you may need to manually trigger focus events or manage the `disabled` state more aggressively. However, for most use cases, no specific "Collaborative Editing" code is required.
