PluginProbe
The Innovative Form Builder – IvyForms / 0.7
The Innovative Form Builder – IvyForms v0.7
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / html-editor / components / IvyImagePopover.vue

IvyImagePopover.vue in The Innovative Form Builder – IvyForms 0.7, at frontend/src/views/_components/html-editor/components/IvyImagePopover.vue

119 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <IvyPopover
3 ref="popoverRef"
4 trigger="click"
5 :width="showUrlInput ? 350 : 200"
6 popper-background="level-2-foreground"
7 :placement="showUrlInput ? 'bottom-end' : 'bottom'"
8 @hide="onHide"
9 >
10 <template v-if="!showUrlInput">
11 <IvyButtonAction
12 type="ghost"
13 class="insert-image-button"
14 priority="secondary"
15 @click.stop.prevent="showUrlInput = true"
16 >
17 {{ getLabel('insert_image_by_url') }}
18 </IvyButtonAction>
19
20 <el-upload :auto-upload="false" :show-file-list="false" :on-change="uploadImage">
21 <template #trigger>
22 <IvyButtonAction type="ghost" priority="secondary">
23 {{ getLabel('upload_image') }}
24 </IvyButtonAction>
25 </template>
26 </el-upload>
27 </template>
28
29 <template v-else>
30 <div class="ivyforms-flex ivyforms-gap-8">
31 <IvyTextInput v-model="imageUrl" :placeholder="getLabel('image_url')" />
32 <IvyButtonAction @click="applyImageUrl" @click.stop.prevent>
33 {{ getLabel('save') }}</IvyButtonAction
34 >
35 </div>
36 <IvyCheckbox v-model="openInNewTab" class="ivyforms-ml-8">
37 {{ getLabel('open_in_new_tab') }}
38 </IvyCheckbox>
39 </template>
40
41 <template #reference>
42 <IvyButtonOption
43 size="s"
44 type="ghost"
45 priority="white"
46 icon-start-category="text-formatting"
47 icon-start="image"
48 @click.stop.prevent
49 />
50 </template>
51 </IvyPopover>
52 </template>
53
54 <script setup lang="ts">
55 import { ref, unref } from 'vue'
56 import { Editor } from '@tiptap/vue-3'
57 import type { UploadFile } from 'element-plus'
58 import IvyTextInput from '@/views/_components/input/IvyTextInput.vue'
59 import IvyButtonOption from '@/views/_components/button/IvyButtonOption.vue'
60 import IvyButtonAction from '@/views/_components/button/IvyButtonAction.vue'
61 import { useLabels } from '@/composables/useLabels'
62 const { getLabel } = useLabels()
63
64 const props = defineProps<{
65 editor: Editor
66 }>()
67
68 const popoverRef = ref(null)
69 const showUrlInput = ref<boolean>(false)
70 const imageUrl = ref<string | null>(null)
71 const openInNewTab = ref<boolean>(false)
72
73 const uploadImage = async (file: UploadFile) => {
74 const url = await readFileDataUrl(file.raw)
75 props.editor.commands.setImage({ src: url })
76 unref(popoverRef).hide()
77 }
78
79 const applyImageUrl = () => {
80 props.editor.commands.setImage({ src: imageUrl.value })
81 unref(popoverRef).hide()
82 }
83
84 const readFileDataUrl = (file: File): Promise<string> => {
85 const reader = new FileReader()
86
87 return new Promise((resolve, reject) => {
88 reader.onload = (readerEvent: ProgressEvent<FileReader>) => {
89 if (readerEvent.target?.result) {
90 resolve(readerEvent.target.result as string)
91 } else {
92 reject(new Error('Failed to read file'))
93 }
94 }
95 reader.onerror = reject
96
97 reader.readAsDataURL(file)
98 })
99 }
100
101 const onHide = () => {
102 imageUrl.value = null
103 showUrlInput.value = false
104 }
105 </script>
106 <style lang="scss">
107 .ivyforms-popover-popper {
108 .insert-image-button {
109 .ivyforms-button-action {
110 span {
111 display: flex;
112 text-overflow: unset;
113 overflow: unset;
114 }
115 }
116 }
117 }
118 </style>
119