Development & Custom Extensions
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:
- Automatic wrapping: Your interface is wrapped by the
form-fieldcomponent. - Event Detection: The wrapper listens for standard DOM
focusinandfocusoutevents bubbling up from your component. - 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.
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.
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
tabindexif 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.
<!-- 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.
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.
Get once-a-month release notes & real‑world code tips...no fluff. 🐰