vue-editify 0.1.25 → 0.1.27

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,9 +8,10 @@
8
8
  justify-content: flex-start;
9
9
  align-items: center;
10
10
  width: 100%;
11
- margin-bottom: 20px;
11
+ margin-bottom: 10px;
12
12
  position: relative;
13
13
  padding-bottom: 6px;
14
+ user-select: none;
14
15
 
15
16
  .editify-attachment-header-slider {
16
17
  position: absolute;
@@ -107,29 +108,57 @@
107
108
 
108
109
  .editify-attachment-upload {
109
110
  display: flex;
110
- justify-content: center;
111
- align-items: center;
111
+ justify-content: space-between;
112
+ align-items: flex-end;
112
113
  width: 100%;
113
114
  padding: 15px 0;
114
- font-size: 36px;
115
- opacity: 0.8;
116
- transition: all 200ms;
117
- position: relative;
118
115
 
119
- &:hover {
120
- cursor: pointer;
121
- opacity: 1;
116
+ input[type='text'] {
117
+ appearance: none;
118
+ -webkit-appearance: none;
119
+ -moz-appearance: none;
120
+ display: block;
121
+ width: 100%;
122
+ margin: 0;
123
+ padding: 4px 2px;
124
+ border: none;
125
+ font-size: @font-size;
126
+ color: @font-color;
127
+ border-bottom: 1px solid @border-color;
128
+ line-height: 1.5;
129
+ transition: border-color 500ms;
130
+ background-color: transparent;
131
+ outline: none;
132
+ box-sizing: border-box;
133
+
134
+ &::-webkit-input-placeholder,
135
+ &::placeholder {
136
+ color: @font-color-disabled;
137
+ font-family: inherit;
138
+ font-size: inherit;
139
+ vertical-align: middle;
140
+ }
122
141
  }
123
142
 
124
- input {
125
- opacity: 0;
126
- position: absolute;
127
- left: 0;
128
- top: 0;
129
- width: 100%;
130
- height: 100%;
131
- z-index: 1;
132
- cursor: pointer;
143
+ .editify-attachment-btn {
144
+ position: relative;
145
+ font-size: 20px;
146
+ line-height: 1;
147
+ opacity: 0.8;
148
+ transition: all 200ms;
149
+ color: @font-color;
150
+ border-radius: 2px;
151
+ padding: 2px;
152
+ margin-left: 15px;
153
+
154
+ &:hover {
155
+ cursor: pointer;
156
+ opacity: 1;
157
+ }
158
+
159
+ input[type='file'] {
160
+ display: none;
161
+ }
133
162
  }
134
163
  }
135
164
  }
@@ -5,17 +5,21 @@
5
5
  <div @click="current = 'remote'" class="editify-attachment-header-item" :class="{ 'editify-active': current == 'remote' }" :style="activeStyle('remote')">{{ $editTrans('remoteAttachment') }}</div>
6
6
  <div class="editify-attachment-header-slider" :class="'editify-' + current" :style="{ backgroundColor: color || '' }"></div>
7
7
  </div>
8
- <!-- 网络图片 -->
8
+ <!-- 远程地址 -->
9
9
  <div class="editify-attachment-remote" v-if="current == 'remote'">
10
- <input v-model.trim="remoteUrl" :placeholder="$editTrans('attachmentUrlPlaceholder')" @blur="handleInputBlur" @focus="handleInputFocus" />
10
+ <input v-model.trim="attachmentName" :placeholder="$editTrans('attachmentNamePlaceholder')" @blur="handleInputBlur" @focus="handleInputFocus" type="text" />
11
+ <input v-model.trim="attachmentUrl" :placeholder="$editTrans('attachmentUrlPlaceholder')" @blur="handleInputBlur" @focus="handleInputFocus" type="url" />
11
12
  <div class="editify-attachment-remote-footer" :style="{ color: color || '' }">
12
13
  <span @click="insertRemoteAttachment">{{ $editTrans('insert') }}</span>
13
14
  </div>
14
15
  </div>
15
- <!-- 上传图片 -->
16
+ <!-- 上传地址 -->
16
17
  <div class="editify-attachment-upload" v-else>
17
- <Icon value="upload"></Icon>
18
- <input :multiple="multiple" :accept="acceptValue" @change="selectFile" type="file" />
18
+ <input v-model.trim="attachmentName" :placeholder="$editTrans('attachmentNamePlaceholder')" @blur="handleInputBlur" @focus="handleInputFocus" type="text" />
19
+ <div class="editify-attachment-btn" @click="triggerFileInput">
20
+ <Icon value="upload"></Icon>
21
+ <input ref="fileInputRef" :multiple="multiple" :accept="accept" @change="selectFile" type="file" />
22
+ </div>
19
23
  </div>
20
24
  </div>
21
25
  </template>
@@ -36,8 +40,12 @@ const $editTrans = inject<(key: string) => any>('$editTrans')!
36
40
 
37
41
  //当前展示的面板,取值remote和upload
38
42
  const current = ref<'remote' | 'upload'>('upload')
39
- //远程图片链接
40
- const remoteUrl = ref<string>('')
43
+ //附件名称
44
+ const attachmentName = ref<string>('')
45
+ //附件远程地址
46
+ const attachmentUrl = ref<string>('')
47
+ //文件选择框
48
+ const fileInputRef = ref<HTMLInputElement | null>(null)
41
49
 
42
50
  const activeStyle = computed<(name: 'remote' | 'upload') => ObjectType>(() => {
43
51
  return (name: 'remote' | 'upload') => {
@@ -49,47 +57,6 @@ const activeStyle = computed<(name: 'remote' | 'upload') => ObjectType>(() => {
49
57
  return {}
50
58
  }
51
59
  })
52
- const acceptValue = computed<string | undefined>(() => {
53
- if (props.accept === 'rar') {
54
- return 'application/x-rar-compressed'
55
- }
56
- if (props.accept === 'zip') {
57
- return 'application/x-zip-compressed'
58
- }
59
- if (props.accept === 'txt') {
60
- return 'text/plain'
61
- }
62
- if (props.accept === 'image') {
63
- return 'image/*'
64
- }
65
- if (props.accept === 'video') {
66
- return 'video/*'
67
- }
68
- if (props.accept === 'audio') {
69
- return 'aduio/*'
70
- }
71
- if (props.accept === 'html') {
72
- return 'text/html'
73
- }
74
- if (props.accept === 'doc') {
75
- return 'application/msword'
76
- }
77
- if (props.accept === 'xml') {
78
- return 'text/xml'
79
- }
80
- if (props.accept === 'js') {
81
- return 'text/javascript'
82
- }
83
- if (props.accept === 'json') {
84
- return 'application/json'
85
- }
86
- if (props.accept === 'ppt') {
87
- return 'application/vnd.ms-powerpoint'
88
- }
89
- if (props.accept === 'pdf') {
90
- return 'application/pdf'
91
- }
92
- })
93
60
 
94
61
  //获取文件后缀
95
62
  const getSuffix = (file: File) => {
@@ -102,21 +69,24 @@ const getSuffix = (file: File) => {
102
69
  //输入框获取焦点
103
70
  const handleInputFocus = (e: Event) => {
104
71
  if (props.color) {
105
- ;(<HTMLInputElement>e.currentTarget).style.borderColor = props.color
72
+ ;(e.currentTarget as HTMLInputElement).style.borderColor = props.color
106
73
  }
107
74
  }
108
75
  //输入框失去焦点
109
76
  const handleInputBlur = (e: Event) => {
110
- ;(<HTMLInputElement>e.currentTarget).style.borderColor = ''
77
+ ;(e.currentTarget as HTMLInputElement).style.borderColor = ''
111
78
  }
112
79
  //插入网络文件
113
80
  const insertRemoteAttachment = () => {
114
- emits('insert', remoteUrl.value)
81
+ emits('insert', attachmentName.value, attachmentUrl.value)
82
+ }
83
+ //触发文件选择框
84
+ const triggerFileInput = () => {
85
+ fileInputRef.value!.click()
115
86
  }
116
87
  //选择文件
117
- const selectFile = async (e: Event) => {
118
- const inputEle = <HTMLInputElement>e.currentTarget
119
- const files = inputEle.files
88
+ const selectFile = async () => {
89
+ const files = fileInputRef.value!.files
120
90
  if (!files || !files.length) {
121
91
  return
122
92
  }
@@ -171,11 +141,11 @@ const selectFile = async (e: Event) => {
171
141
  }
172
142
  }
173
143
  attachments.forEach(url => {
174
- emits('insert', url)
144
+ emits('insert', attachmentName.value, url)
175
145
  })
176
146
  }
177
147
  //清空文件选择框
178
- inputEle.value = ''
148
+ fileInputRef.value!.value = ''
179
149
  }
180
150
 
181
151
  //监听current变更触发change事件
@@ -10,7 +10,7 @@ export const InsertAttachmentProps = {
10
10
  },
11
11
  //可选择的文件类型
12
12
  accept: {
13
- type: String as PropType<'rar' | 'zip' | 'txt' | 'image' | 'video' | 'audio' | 'html' | 'doc' | 'xml' | 'js' | 'json' | 'ppt' | 'pdf' | null>,
13
+ type: String,
14
14
  default: null
15
15
  },
16
16
  //支持的类型数组
@@ -0,0 +1,48 @@
1
+ // vite.config.ts
2
+ import { defineConfig } from "file:///Users/lingkai/Desktop/%E5%89%8D%E7%AB%AF%E5%BA%93/vue-editify/node_modules/vite/dist/node/index.js";
3
+ import vue from "file:///Users/lingkai/Desktop/%E5%89%8D%E7%AB%AF%E5%BA%93/vue-editify/node_modules/@vitejs/plugin-vue/dist/index.mjs";
4
+ import dts from "file:///Users/lingkai/Desktop/%E5%89%8D%E7%AB%AF%E5%BA%93/vue-editify/node_modules/vite-plugin-dts/dist/index.mjs";
5
+ import path from "path";
6
+ var __vite_injected_original_dirname = "/Users/lingkai/Desktop/\u524D\u7AEF\u5E93/vue-editify";
7
+ var vite_config_default = defineConfig({
8
+ plugins: [vue(), dts()],
9
+ build: {
10
+ //打包后的目录名称
11
+ outDir: "lib",
12
+ minify: "terser",
13
+ lib: {
14
+ entry: path.resolve(__vite_injected_original_dirname, "src/index.ts"),
15
+ name: "editify",
16
+ fileName: (format) => `editify.${format}.js`
17
+ },
18
+ rollupOptions: {
19
+ // 确保外部化处理那些你不想打包进库的依赖
20
+ external: ["vue"],
21
+ output: {
22
+ // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
23
+ globals: {
24
+ vue: "Vue"
25
+ },
26
+ exports: "named"
27
+ }
28
+ },
29
+ sourcemap: false
30
+ //是否构建source map 文件
31
+ },
32
+ css: {
33
+ preprocessorOptions: {
34
+ less: {
35
+ // 使用 less 编写样式的 UI 库(如 antd)时建议加入这个设置
36
+ javascriptEnabled: true,
37
+ additionalData: `@import "src/css/base.less";`
38
+ }
39
+ }
40
+ },
41
+ server: {
42
+ host: "0.0.0.0"
43
+ }
44
+ });
45
+ export {
46
+ vite_config_default as default
47
+ };
48
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvbGluZ2thaS9EZXNrdG9wL1x1NTI0RFx1N0FFRlx1NUU5My92dWUtZWRpdGlmeVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL2xpbmdrYWkvRGVza3RvcC9cdTUyNERcdTdBRUZcdTVFOTMvdnVlLWVkaXRpZnkvdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL1VzZXJzL2xpbmdrYWkvRGVza3RvcC8lRTUlODklOEQlRTclQUIlQUYlRTUlQkElOTMvdnVlLWVkaXRpZnkvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJ1xuaW1wb3J0IHZ1ZSBmcm9tICdAdml0ZWpzL3BsdWdpbi12dWUnXG5pbXBvcnQgZHRzIGZyb20gJ3ZpdGUtcGx1Z2luLWR0cydcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG5cdHBsdWdpbnM6IFt2dWUoKSwgZHRzKCldLFxuXHRidWlsZDoge1xuXHRcdC8vXHU2MjUzXHU1MzA1XHU1NDBFXHU3Njg0XHU3NkVFXHU1RjU1XHU1NDBEXHU3OUYwXG5cdFx0b3V0RGlyOiAnbGliJyxcblx0XHRtaW5pZnk6ICd0ZXJzZXInLFxuXHRcdGxpYjoge1xuXHRcdFx0ZW50cnk6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICdzcmMvaW5kZXgudHMnKSxcblx0XHRcdG5hbWU6ICdlZGl0aWZ5Jyxcblx0XHRcdGZpbGVOYW1lOiBmb3JtYXQgPT4gYGVkaXRpZnkuJHtmb3JtYXR9LmpzYFxuXHRcdH0sXG5cdFx0cm9sbHVwT3B0aW9uczoge1xuXHRcdFx0Ly8gXHU3ODZFXHU0RkREXHU1OTE2XHU5MEU4XHU1MzE2XHU1OTA0XHU3NDA2XHU5MEEzXHU0RTlCXHU0RjYwXHU0RTBEXHU2MEYzXHU2MjUzXHU1MzA1XHU4RkRCXHU1RTkzXHU3Njg0XHU0RjlEXHU4RDU2XG5cdFx0XHRleHRlcm5hbDogWyd2dWUnXSxcblx0XHRcdG91dHB1dDoge1xuXHRcdFx0XHQvLyBcdTU3MjggVU1EIFx1Njc4NFx1NUVGQVx1NkEyMVx1NUYwRlx1NEUwQlx1NEUzQVx1OEZEOVx1NEU5Qlx1NTkxNlx1OTBFOFx1NTMxNlx1NzY4NFx1NEY5RFx1OEQ1Nlx1NjNEMFx1NEY5Qlx1NEUwMFx1NEUyQVx1NTE2OFx1NUM0MFx1NTNEOFx1OTFDRlxuXHRcdFx0XHRnbG9iYWxzOiB7XG5cdFx0XHRcdFx0dnVlOiAnVnVlJ1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRleHBvcnRzOiAnbmFtZWQnXG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzb3VyY2VtYXA6IGZhbHNlIC8vXHU2NjJGXHU1NDI2XHU2Nzg0XHU1RUZBc291cmNlIG1hcCBcdTY1ODdcdTRFRjZcblx0fSxcblx0Y3NzOiB7XG5cdFx0cHJlcHJvY2Vzc29yT3B0aW9uczoge1xuXHRcdFx0bGVzczoge1xuXHRcdFx0XHQvLyBcdTRGN0ZcdTc1MjggbGVzcyBcdTdGMTZcdTUxOTlcdTY4MzdcdTVGMEZcdTc2ODQgVUkgXHU1RTkzXHVGRjA4XHU1OTgyIGFudGRcdUZGMDlcdTY1RjZcdTVFRkFcdThCQUVcdTUyQTBcdTUxNjVcdThGRDlcdTRFMkFcdThCQkVcdTdGNkVcblx0XHRcdFx0amF2YXNjcmlwdEVuYWJsZWQ6IHRydWUsXG5cdFx0XHRcdGFkZGl0aW9uYWxEYXRhOiBgQGltcG9ydCBcInNyYy9jc3MvYmFzZS5sZXNzXCI7YFxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblx0c2VydmVyOiB7XG5cdFx0aG9zdDogJzAuMC4wLjAnXG5cdH1cbn0pXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQTRULFNBQVMsb0JBQW9CO0FBQ3pWLE9BQU8sU0FBUztBQUNoQixPQUFPLFNBQVM7QUFDaEIsT0FBTyxVQUFVO0FBSGpCLElBQU0sbUNBQW1DO0FBS3pDLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzNCLFNBQVMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQUEsRUFDdEIsT0FBTztBQUFBO0FBQUEsSUFFTixRQUFRO0FBQUEsSUFDUixRQUFRO0FBQUEsSUFDUixLQUFLO0FBQUEsTUFDSixPQUFPLEtBQUssUUFBUSxrQ0FBVyxjQUFjO0FBQUEsTUFDN0MsTUFBTTtBQUFBLE1BQ04sVUFBVSxZQUFVLFdBQVcsTUFBTTtBQUFBLElBQ3RDO0FBQUEsSUFDQSxlQUFlO0FBQUE7QUFBQSxNQUVkLFVBQVUsQ0FBQyxLQUFLO0FBQUEsTUFDaEIsUUFBUTtBQUFBO0FBQUEsUUFFUCxTQUFTO0FBQUEsVUFDUixLQUFLO0FBQUEsUUFDTjtBQUFBLFFBQ0EsU0FBUztBQUFBLE1BQ1Y7QUFBQSxJQUNEO0FBQUEsSUFDQSxXQUFXO0FBQUE7QUFBQSxFQUNaO0FBQUEsRUFDQSxLQUFLO0FBQUEsSUFDSixxQkFBcUI7QUFBQSxNQUNwQixNQUFNO0FBQUE7QUFBQSxRQUVMLG1CQUFtQjtBQUFBLFFBQ25CLGdCQUFnQjtBQUFBLE1BQ2pCO0FBQUEsSUFDRDtBQUFBLEVBQ0Q7QUFBQSxFQUNBLFFBQVE7QUFBQSxJQUNQLE1BQU07QUFBQSxFQUNQO0FBQ0QsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K