Skip to content

Commit 8236b6d

Browse files
committed
fix(FloatingButtons): group smartpicker button and drag handle together
- The button group follows the cursor now - The button group is top-aligned to hovered paragraph node - The drag handle button has cursor type `grab` - Not displayed on mobile and full width view Also removes block margin from link previews. We already have margin between paragraphs and it makes the floating buttons look off otherwise. Fixes: #7272 Fixes: #7604 Signed-off-by: Jonas <jonas@freesources.org>
1 parent 70e48dd commit 8236b6d

6 files changed

Lines changed: 116 additions & 258 deletions

File tree

src/components/Editor/ContentContainer.vue

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@
1414
<EditorOutline />
1515
</div>
1616
<slot />
17-
<DragHandle :editor="editor" class="drag-handle--button">
18-
<NcButton type="tertiary-no-background" size="normal">
19-
<template #icon>
20-
<DragVerticalIcon :size="20" />
21-
</template>
22-
</NcButton>
23-
</DragHandle>
17+
<FloatingButtons v-if="!isMobile && !isFullWidth" />
2418
<EditorContent
2519
role="document"
2620
class="editor__content text-editor__content"
@@ -30,27 +24,27 @@
3024
</template>
3125

3226
<script>
33-
import NcButton from '@nextcloud/vue/components/NcButton'
34-
import { DragHandle } from '@tiptap/extension-drag-handle-vue-2'
27+
import { useIsMobile } from '@nextcloud/vue/composables/useIsMobile'
3528
import { EditorContent } from '@tiptap/vue-2'
36-
import DragVerticalIcon from 'vue-material-design-icons/DragVertical.vue'
3729
import { useEditor } from '../../composables/useEditor.ts'
30+
import { useEditorWidth } from '../../composables/useEditorWidth.ts'
3831
import EditorOutline from './EditorOutline.vue'
32+
import FloatingButtons from './FloatingButtons.vue'
3933
import { useOutlineStateMixin } from './Wrapper.provider.js'
4034
4135
export default {
4236
name: 'ContentContainer',
4337
components: {
4438
EditorContent,
4539
EditorOutline,
46-
NcButton,
47-
DragHandle,
48-
DragVerticalIcon,
40+
FloatingButtons,
4941
},
5042
mixins: [useOutlineStateMixin],
5143
setup() {
44+
const isMobile = useIsMobile()
5245
const { editor } = useEditor()
53-
return { editor }
46+
const { isFullWidth } = useEditorWidth()
47+
return { editor, isMobile, isFullWidth }
5448
},
5549
computed: {
5650
showOutline() {
@@ -72,12 +66,6 @@ export default {
7266
}
7367
}
7468
75-
.ie {
76-
.editor__content:deep(.ProseMirror) {
77-
padding-top: 50px;
78-
}
79-
}
80-
8169
.text-editor__content-wrapper {
8270
--side-width: calc((100% - var(--text-editor-max-width)) / 2);
8371
display: grid;
@@ -104,12 +92,4 @@ export default {
10492
}
10593
}
10694
}
107-
108-
.drag-handle--button {
109-
color: var(--color-maxcontrast);
110-
position: absolute;
111-
left: -60px;
112-
transform: translate(0, -20%);
113-
padding-right: 24px;
114-
}
11595
</style>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
6+
<template>
7+
<DragHandle
8+
:editor="editor"
9+
class="floating-buttons"
10+
:on-node-change="onNodeChange">
11+
<NcButton
12+
type="tertiary-no-background"
13+
size="small"
14+
:title="t('text', 'Insert below')"
15+
@click="onOpenSmartPicker">
16+
<template #icon>
17+
<PlusIcon :size="16" />
18+
</template>
19+
</NcButton>
20+
<NcButton
21+
type="tertiary-no-background"
22+
size="small"
23+
class="drag-button"
24+
:title="t('text', 'Click for options, hold to drag')">
25+
<template #icon>
26+
<DragVerticalIcon :size="16" />
27+
</template>
28+
</NcButton>
29+
</DragHandle>
30+
</template>
31+
32+
<script>
33+
import { t } from '@nextcloud/l10n'
34+
import NcButton from '@nextcloud/vue/components/NcButton'
35+
import { DragHandle } from '@tiptap/extension-drag-handle-vue-2'
36+
import DragVerticalIcon from 'vue-material-design-icons/DragVertical.vue'
37+
import PlusIcon from 'vue-material-design-icons/Plus.vue'
38+
import { useEditor } from '../../composables/useEditor.ts'
39+
40+
export default {
41+
name: 'FloatingButtons',
42+
43+
components: {
44+
DragHandle,
45+
DragVerticalIcon,
46+
NcButton,
47+
PlusIcon,
48+
},
49+
50+
setup() {
51+
const { editor } = useEditor()
52+
return { editor }
53+
},
54+
55+
data() {
56+
return {
57+
node: null,
58+
pos: -1,
59+
}
60+
},
61+
62+
computed: {
63+
isHeadingNode() {
64+
return this.node?.type === this.editor.schema.nodes.heading
65+
},
66+
},
67+
68+
methods: {
69+
onNodeChange({ node, pos }) {
70+
this.node = node
71+
this.pos = pos
72+
},
73+
onOpenSmartPicker() {
74+
if (!this.node || this.pos === -1) {
75+
return
76+
}
77+
78+
// Node has no children or just text children and no text content
79+
const { schema } = this.editor
80+
const emptyNode = this.node.textContent.trim() === ''
81+
&& (this.node.children.length === 0 || this.node.children.every((n) => n.type === schema.nodes.text))
82+
83+
// Insert at the end of the node
84+
const pos = emptyNode ? this.pos + 1 : this.pos + this.node.nodeSize
85+
this.editor.chain()
86+
.insertContentAt(pos, '/')
87+
.focus()
88+
.run()
89+
},
90+
t,
91+
},
92+
}
93+
</script>
94+
95+
<style scoped lang="scss">
96+
.floating-buttons {
97+
display: flex;
98+
}
99+
100+
.drag-button {
101+
cursor: grab;
102+
103+
:deep(span), :deep(svg) {
104+
cursor: grab !important;
105+
}
106+
}
107+
</style>

src/components/Editor/SmartPickerMenu.vue

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/nodes/Paragraph.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55

66
import TiptapParagraph from '@tiptap/extension-paragraph'
7-
import currentLineMenu from '../plugins/currentLineMenu.js'
87

98
const Paragraph = TiptapParagraph.extend({
109
parseHTML() {
@@ -42,10 +41,6 @@ const Paragraph = TiptapParagraph.extend({
4241
},
4342
}
4443
},
45-
46-
addProseMirrorPlugins() {
47-
return [currentLineMenu({ editor: this.editor })]
48-
},
4944
})
5045

5146
export default Paragraph

src/nodes/Preview.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export default {
7979
8080
:deep(div.widgets--list a.widget-default) {
8181
color: var(--color-main-text);
82+
margin: 0;
8283
padding: 0;
8384
text-decoration: none;
8485
max-width: calc(100vw - 156px);

0 commit comments

Comments
 (0)