upd
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
<div class="panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-title-row">
|
||||
<h2 class="panel-title">Selected items</h2>
|
||||
<h2 class="panel-title">
|
||||
Selected items
|
||||
</h2>
|
||||
<span v-if="items.length" class="item-count">{{ items.length }}</span>
|
||||
</div>
|
||||
<div class="search-wrap">
|
||||
@@ -38,10 +40,10 @@
|
||||
>
|
||||
<span class="drag-handle" title="Drag to reorder" aria-hidden="true">
|
||||
<svg width="8" height="12" viewBox="0 0 8 12" fill="currentColor">
|
||||
<circle cx="2" cy="2" r="1.2" />
|
||||
<circle cx="6" cy="2" r="1.2" />
|
||||
<circle cx="2" cy="6" r="1.2" />
|
||||
<circle cx="6" cy="6" r="1.2" />
|
||||
<circle cx="2" cy="2" r="1.2" />
|
||||
<circle cx="6" cy="2" r="1.2" />
|
||||
<circle cx="2" cy="6" r="1.2" />
|
||||
<circle cx="6" cy="6" r="1.2" />
|
||||
<circle cx="2" cy="10" r="1.2" />
|
||||
<circle cx="6" cy="10" r="1.2" />
|
||||
</svg>
|
||||
@@ -85,7 +87,7 @@ const emit = defineEmits<{
|
||||
(e: 'update:search', val: string): void
|
||||
(e: 'loadMore'): void
|
||||
(e: 'deselect', id: number): void
|
||||
(e: 'reorder', ids: number[]): void
|
||||
(e: 'reorder', id: number, afterId: number | null): void
|
||||
}>()
|
||||
|
||||
const sentinel = ref<HTMLElement | null>(null)
|
||||
@@ -127,9 +129,10 @@ watch(() => props.items, (val) => {
|
||||
localItems.value = [...val]
|
||||
}, { deep: true })
|
||||
|
||||
function onDragEnd(): void {
|
||||
const ids = localItems.value.map(i => i.id!)
|
||||
emit('reorder', ids)
|
||||
function onDragEnd(event: { oldIndex: number, newIndex: number }): void {
|
||||
const moved = localItems.value[event.newIndex]
|
||||
const after = event.newIndex > 0 ? localItems.value[event.newIndex - 1] : null
|
||||
emit('reorder', moved.id!, after?.id ?? null)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -143,6 +146,7 @@ function onDragEnd(): void {
|
||||
|
||||
/* ── Header ── */
|
||||
.panel-header {
|
||||
height: 108px;
|
||||
padding: 18px 20px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
@@ -206,7 +210,9 @@ function onDragEnd(): void {
|
||||
font-size: 0.825rem;
|
||||
color: var(--text-primary);
|
||||
outline: none;
|
||||
transition: border-color 150ms ease, background 150ms ease;
|
||||
transition:
|
||||
border-color 150ms ease,
|
||||
background 150ms ease;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--text-muted);
|
||||
@@ -223,9 +229,16 @@ function onDragEnd(): void {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar { width: 3px; }
|
||||
&::-webkit-scrollbar-track { background: transparent; }
|
||||
&::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
||||
&::-webkit-scrollbar {
|
||||
width: 3px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-list {
|
||||
@@ -235,8 +248,14 @@ function onDragEnd(): void {
|
||||
}
|
||||
|
||||
@keyframes item-in {
|
||||
from { opacity: 0; transform: translateY(6px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.item-row {
|
||||
@@ -252,8 +271,12 @@ function onDragEnd(): void {
|
||||
&:hover {
|
||||
background: var(--surface-subtle);
|
||||
|
||||
.action-btn { opacity: 1; }
|
||||
.drag-handle { color: var(--text-secondary); }
|
||||
.action-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
.drag-handle {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +290,9 @@ function onDragEnd(): void {
|
||||
transition: color 120ms ease;
|
||||
user-select: none;
|
||||
|
||||
&:active { cursor: grabbing; }
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
|
||||
.item-order {
|
||||
@@ -305,7 +330,10 @@ function onDragEnd(): void {
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
flex-shrink: 0;
|
||||
transition: color 120ms ease, background 120ms ease, opacity 120ms ease;
|
||||
transition:
|
||||
color 120ms ease,
|
||||
background 120ms ease,
|
||||
opacity 120ms ease;
|
||||
|
||||
&:hover {
|
||||
color: var(--text-primary);
|
||||
@@ -332,14 +360,24 @@ function onDragEnd(): void {
|
||||
background: var(--text-muted);
|
||||
animation: dot-blink 1.2s ease-in-out infinite;
|
||||
|
||||
&:nth-child(2) { animation-delay: 0.2s; }
|
||||
&:nth-child(3) { animation-delay: 0.4s; }
|
||||
&:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dot-blink {
|
||||
0%, 80%, 100% { opacity: 0.25; }
|
||||
40% { opacity: 1; }
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
opacity: 0.25;
|
||||
}
|
||||
40% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
|
||||
Reference in New Issue
Block a user