feat: expand VLAN color palette to 50 presets in a 5×10 grid

Replace the 10-color row with a 5-row × 10-column palette covering
red, rose, orange, amber, yellow, green, teal, cyan, blue, indigo,
violet, purple, fuchsia and gray families. Selected swatch is
highlighted with a border ring.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 12:47:47 +02:00
parent fb6bcdb968
commit dc04567c48
+22 -11
View File
@@ -59,20 +59,22 @@
</div>
<div class="field">
<label>{{ t('color') }}</label>
<div class="color-row">
<div class="color-picker-row">
<input v-model="form.color" type="color" />
<span>{{ form.color }}</span>
<span class="color-hex">{{ form.color }}</span>
</div>
<div class="color-presets">
<div
v-for="c in presetColors"
:key="c"
class="preset"
:class="{ selected: form.color.toLowerCase() === c.toLowerCase() }"
:style="{ background: c }"
:title="c"
@click="form.color = c"
></div>
</div>
</div>
</div>
<div class="modal-actions">
<button type="button" class="btn-secondary" @click="showForm = false">{{ t('cancel') }}</button>
<button type="submit" class="btn-primary">{{ editing ? t('save') : t('create') }}</button>
@@ -96,8 +98,16 @@ const editing = ref(null)
const form = reactive({ vlan_id: '', name: '', cidr: '', color: '#4A90D9' })
const presetColors = [
'#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6',
'#EC4899', '#14B8A6', '#F97316', '#6366F1', '#84CC16'
// Rouges / Roses
'#FCA5A5', '#EF4444', '#DC2626', '#991B1B', '#FDA4AF', '#F43F5E', '#E11D48', '#9F1239', '#FBB6CE', '#F472B6',
// Oranges / Ambers / Jaunes
'#FED7AA', '#F97316', '#EA580C', '#9A3412', '#FDE68A', '#F59E0B', '#D97706', '#92400E', '#FEF08A', '#EAB308',
// Verts / Teals
'#D9F99D', '#84CC16', '#22C55E', '#16A34A', '#BBF7D0', '#10B981', '#059669', '#99F6E4', '#14B8A6', '#0D9488',
// Cyans / Bleus
'#BAE6FD', '#0EA5E9', '#0284C7', '#0C4A6E', '#BFDBFE', '#3B82F6', '#2563EB', '#1E3A8A', '#C7D2FE', '#6366F1',
// Violets / Gris
'#DDD6FE', '#8B5CF6', '#7C3AED', '#4C1D95', '#E9D5FF', '#A855F7', '#D946EF', '#CBD5E1', '#94A3B8', '#1E293B',
]
function openAdd() {
@@ -210,12 +220,13 @@ code { background: var(--bg-page); padding: 2px 6px; border-radius: 4px; font-si
}
.field input:focus { outline: none; border-color: #3B82F6; }
.color-row { display: flex; align-items: center; gap: 12px; }
.color-row input[type="color"] { width: 40px; height: 36px; border: none; border-radius: 6px; cursor: pointer; padding: 0; }
.color-row span { font-size: 13px; color: var(--text-muted); font-family: monospace; }
.color-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.preset { width: 20px; height: 20px; border-radius: 4px; cursor: pointer; transition: transform 0.1s; }
.preset:hover { transform: scale(1.2); }
.color-picker-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.color-picker-row input[type="color"] { width: 40px; height: 36px; border: none; border-radius: 6px; cursor: pointer; padding: 0; }
.color-hex { font-size: 13px; color: var(--text-muted); font-family: monospace; }
.color-presets { display: grid; grid-template-columns: repeat(10, 1fr); gap: 5px; }
.preset { aspect-ratio: 1; border-radius: 5px; cursor: pointer; transition: transform 0.1s; border: 2.5px solid transparent; box-sizing: border-box; }
.preset:hover { transform: scale(1.15); }
.preset.selected { border-color: var(--text-primary); transform: scale(1.1); }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 24px; }
</style>