Розробка кастомних дисплеїв (Displays) Directus
Display Extension — компонент Vue 3 для відображення значення поля у списку (collection view) та формі перегляду. Якщо стандартні displays (raw, datetime, boolean, related-values) не підходять, створюється кастомний.
Коли потрібен кастомний Display
- Показувати кольоровий кружечок для поля
colorзамість HEX-строки - Рендерити прогрес-бар для числового поля
progress - Відображати іконку статусу замість тексту
- Форматувати складні JSON-дані як таблицю
Базовий Display
npx create-directus-extension@latest
# Type: display
# Name: color-display
<!-- src/display.vue -->
<template>
<div class="color-display">
<div
v-if="value"
class="color-swatch"
:style="{ background: value }"
/>
<span class="color-value">{{ value || '—' }}</span>
</div>
</template>
<script setup lang="ts">
defineProps<{ value: string | null }>()
</script>
<style scoped>
.color-display { display: flex; align-items: center; gap: 6px; }
.color-swatch { width: 16px; height: 16px; border-radius: 3px; border: 1px solid rgba(0,0,0,0.1); flex-shrink: 0; }
.color-value { font-size: 12px; font-family: monospace; }
</style>
// src/index.ts
import DisplayComponent from './display.vue'
export default {
id: 'color-display',
name: 'Color Swatch',
icon: 'palette',
description: 'Показує колір як кольоровий кружечок',
component: DisplayComponent,
types: ['string'],
options: null, // немає додаткових налаштувань
}
Display статусу з іконкою
<template>
<div class="status-display" :class="`status-${value}`">
<v-icon :name="statusConfig[value]?.icon || 'circle'" small />
<span>{{ statusConfig[value]?.label || value }}</span>
</div>
</template>
<script setup lang="ts">
defineProps<{ value: string | null }>()
const statusConfig: Record<string, { icon: string; label: string }> = {
draft: { icon: 'edit', label: 'Чернетка' },
review: { icon: 'visibility', label: 'На перевірці' },
published: { icon: 'check_circle', label: 'Опубліковано' },
archived: { icon: 'archive', label: 'Архів' },
}
</script>
<style scoped>
.status-display { display: flex; align-items: center; gap: 4px; font-size: 12px; }
.status-published { color: var(--success); }
.status-draft { color: var(--warning); }
.status-archived { color: var(--foreground-subdued); }
</style>
Display прогресу
<template>
<div class="progress-display">
<div class="progress-bar">
<div class="progress-fill" :style="{ width: `${percentage}%`, background: color }" />
</div>
<span class="progress-label">{{ value }}{{ suffix }}</span>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
const props = defineProps<{
value: number | null
maxValue?: number
suffix?: string
}>()
const percentage = computed(() =>
Math.min(100, ((props.value || 0) / (props.maxValue || 100)) * 100)
)
const color = computed(() =>
percentage.value >= 80 ? '#4CAF50' : percentage.value >= 50 ? '#FF9800' : '#F44336'
)
</script>
// Реєстрація з опціями
export default {
id: 'progress-display',
name: 'Progress Bar',
icon: 'linear_scale',
component: DisplayComponent,
types: ['integer', 'float', 'decimal'],
options: [
{
field: 'maxValue',
name: 'Max Value',
type: 'integer',
meta: { interface: 'input', default_value: 100 },
},
{
field: 'suffix',
name: 'Suffix',
type: 'string',
meta: { interface: 'input', options: { placeholder: '%' } },
},
],
}
Підключення Display до поля
У Settings → Data Model → поле → Interface & Display → виберіть Display = Color Swatch або Progress Bar.
Терміни
Розробка 2–3 кастомних displays — 1 день.







