fix(frontend): ドラッグハンドルがあるのに設定されていないドラッグUIを修正 (#17472)

This commit is contained in:
かっこかり 2026-05-22 08:55:55 +09:00 committed by GitHub
commit c02fe955cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 27 additions and 12 deletions

View file

@ -44,11 +44,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkDraggable
:modelValue="pinnedNoteIds.map(id => ({ id }))"
direction="vertical"
manualDragStart
@update:modelValue="v => pinnedNoteIds = v.map(x => x.id)"
>
<template #default="{ item }">
<template #default="{ item, dragStart }">
<div :class="$style.pinnedNote">
<button class="_button" :class="$style.pinnedNoteHandle"><i class="ti ti-menu"></i></button>
<button class="_button" :class="$style.pinnedNoteHandle" tabindex="-1" :draggable="true" @dragstart.stop="dragStart"><i class="ti ti-menu"></i></button>
{{ item.id }}
<button class="_button" :class="$style.pinnedNoteRemove" @click="removePinnedNote(item.id)"><i class="ti ti-x"></i></button>
</div>

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => emit('remove')">
<XContainer :draggable="true" :dragStartCallback="dragStartCallback" @remove="() => emit('remove')">
<template #header><i class="ti ti-photo"></i> {{ i18n.ts._pages.blocks.image }}</template>
<template #func>
<button @click="choose()">
@ -30,6 +30,7 @@ import { i18n } from '@/i18n.js';
import { chooseDriveFile } from '@/utility/drive.js';
const props = defineProps<{
dragStartCallback?: (ev: DragEvent) => void;
modelValue: Misskey.entities.PageBlock & { type: 'image' };
}>();

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => emit('remove')">
<XContainer :draggable="true" :dragStartCallback="dragStartCallback" @remove="() => emit('remove')">
<template #header><i class="ti ti-note"></i> {{ i18n.ts._pages.blocks.note }}</template>
<section style="padding: 16px;" class="_gaps_s">
@ -34,6 +34,7 @@ import { misskeyApi } from '@/utility/misskey-api.js';
import { i18n } from '@/i18n.js';
const props = defineProps<{
dragStartCallback?: (ev: DragEvent) => void;
modelValue: Misskey.entities.PageBlock & { type: 'note' };
}>();

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => emit('remove')">
<XContainer :draggable="true" :dragStartCallback="dragStartCallback" @remove="() => emit('remove')">
<template #header><i class="ti ti-note"></i> {{ props.modelValue.title }}</template>
<template #func>
<button class="_button" @click="rename()">
@ -35,6 +35,7 @@ import { getPageBlockList } from '@/pages/page-editor/common.js';
const XBlocks = defineAsyncComponent(() => import('../page-editor.blocks.vue'));
const props = defineProps<{
dragStartCallback?: (ev: DragEvent) => void;
modelValue: Extract<Misskey.entities.PageBlock, { type: 'section'; }>,
}>();

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<!-- eslint-disable vue/no-mutating-props -->
<XContainer :draggable="true" @remove="() => emit('remove')">
<XContainer :draggable="true" :dragStartCallback="dragStartCallback" @remove="() => emit('remove')">
<template #header><i class="ti ti-align-left"></i> {{ i18n.ts._pages.blocks.text }}</template>
<section>
@ -22,6 +22,7 @@ import { i18n } from '@/i18n.js';
import { Autocomplete } from '@/utility/autocomplete.js';
const props = defineProps<{
dragStartCallback?: (ev: DragEvent) => void;
modelValue: Misskey.entities.PageBlock & { type: 'text' }
}>();

View file

@ -9,19 +9,27 @@ SPDX-License-Identifier: AGPL-3.0-only
direction="vertical"
withGaps
canNest
manualDragStart
group="pageBlocks"
@update:modelValue="v => emit('update:modelValue', v)"
>
<template #default="{ item }">
<template #default="{ item, dragStart }">
<div>
<!-- divが無いとエラーになる -->
<component :is="getComponent(item.type) as any" :modelValue="item" @update:modelValue="updateItem" @remove="() => removeItem(item)"/>
<component
:is="getComponent(item.type)"
:modelValue="item"
:dragStartCallback="dragStart"
@update:modelValue="updateItem"
@remove="() => removeItem(item)"
/>
</div>
</template>
</MkDraggable>
</template>
<script lang="ts" setup>
import type { Component } from 'vue';
import * as Misskey from 'misskey-js';
import XSection from './els/page-editor.el.section.vue';
import XText from './els/page-editor.el.text.vue';
@ -29,7 +37,7 @@ import XImage from './els/page-editor.el.image.vue';
import XNote from './els/page-editor.el.note.vue';
import MkDraggable from '@/components/MkDraggable.vue';
function getComponent(type: Misskey.entities.Page['content'][number]['type']) {
function getComponent(type: Misskey.entities.Page['content'][number]['type']): Component {
switch (type) {
case 'section': return XSection;
case 'text': return XText;

View file

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="removable" class="_button" @click="remove()">
<i class="ti ti-trash"></i>
</button>
<button v-if="draggable" class="drag-handle _button">
<button v-if="draggable" class="drag-handle _button" tabindex="-1" :draggable="true" @dragstart.stop="dragStartCallback">
<i class="ti ti-menu-2"></i>
</button>
<button class="_button" @click="toggleContent(!showBody)">
@ -34,6 +34,7 @@ const props = withDefaults(defineProps<{
expanded?: boolean;
removable?: boolean;
draggable?: boolean;
dragStartCallback?: (ev: DragEvent) => void;
}>(), {
expanded: true,
removable: true,

View file

@ -12,13 +12,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkDraggable
v-model="items"
direction="vertical"
manualDragStart
>
<template #default="{ item }">
<template #default="{ item, dragStart }">
<div
v-if="item.type === '-' || navbarItemDef[item.type]"
:class="$style.item"
>
<button class="_button" :class="$style.itemHandle"><i class="ti ti-menu"></i></button>
<button class="_button" :class="$style.itemHandle" tabindex="-1" :draggable="true" @dragstart.stop="dragStart"><i class="ti ti-menu"></i></button>
<i class="ti-fw" :class="[$style.itemIcon, navbarItemDef[item.type]?.icon]"></i><span :class="$style.itemText">{{ navbarItemDef[item.type]?.title ?? i18n.ts.divider }}</span>
<button class="_button" :class="$style.itemRemove" @click="removeItem(item.id)"><i class="ti ti-x"></i></button>
</div>